是否有一个用于Try
在 Vavr 中组合实例的 api,类似于 Scalaz 应用运算符的|@|
工作方式?
具体来说,如果我有两个以上的Try
实例,例如Try<X>
和Try<Y>
,Try<Z>
我想使用 3-arg 函数以应用方式组合这些实例。
我正在寻找类似于以下内容的函数签名:
static <X, Y, Z, R> Try<R> combine(Try<X> x, Try<Y> y, Try<Z> z, Function3<X,Y,Z,R> func
是否有一个用于Try
在 Vavr 中组合实例的 api,类似于 Scalaz 应用运算符的|@|
工作方式?
具体来说,如果我有两个以上的Try
实例,例如Try<X>
和Try<Y>
,Try<Z>
我想使用 3-arg 函数以应用方式组合这些实例。
我正在寻找类似于以下内容的函数签名:
static <X, Y, Z, R> Try<R> combine(Try<X> x, Try<Y> y, Try<Z> z, Function3<X,Y,Z,R> func
据我所知,它不直接支持这种用法。但是,您可以使用 flatMap 实现它:
static <X, Y, Z, R> Try<R> combine(Try<X> tx, Try<Y> ty, Try<Z> tz, Function3<X,Y,Z,R> func) {
return tx.flatMap(x -> ty.flatMap(y -> tz.map(z -> func.apply(x, y, z))));
}
如果每个 Try 值都包含相同的类型,那么您可以使用sequence
操作:
public static void main(String[] args) {
List<Try<String>> lt = List.of(Try.success("A"), Try.success("B"), Try.success("C"));
Try<List<String>> tl = sequence(lt);
System.out.println(tl);
}
static <T> Try<List<T>> sequence(List<Try<T>> lt) {
return lt.foldRight(
Try.success(List.empty()),
(tt, tl) -> tt.flatMap(t -> tl.flatMap(l -> Try.success(l.prepend(t))))
);
}
如果您比较输入和输出类型,您会发现这实际上交换了容器Try
和List
容器的位置。这对于 monad 来说是相当惯用的,尽管通常您会使用应用地图操作而不是 flatMap 来实现它。
或者,使用Validation,它旨在用于应用风格(通过Validation.combine
)。