在 Vavr 中结合 Either's?
Combining Either's in Vavr?
我有几个 Vavr Either,我想为每个 Either 调用一个具有 Right
值的函数。例如:
Either<MyError, String> either1 = ..
Either<MyError, String> either2 = ..
Either<MyError, String> either3 = ..
Either<MyError, String>> methodRequiringAllInputs(String, String, String) {
..
}
我当然可以这样做:
either1.flatMap { value1 ->
either2.flatMap { value2 ->
either3.flatMap { value3 ->
methodRequiringAllInputs(value1, value2, value3);
}
}
}
但这很难看。在其他语言中,您可以只使用诸如 do-notation 或 for comprehensions 之类的东西来展平结构。我知道 Vavr 有一个 Validation 的概念,它是一个允许你做的应用函子:
Validation<MyError, String> validation1 = ..
Validation<MyError, String> validation2 = ..
Validation<MyError, String> validation3 = ..
Validation.combine(validation1, validation2, validation3)
.ap((validationValue1,validationValue2,validationValue3) -> .. );
哪个更好。
我的问题是在 Vavr 中是否存在类似的东西来避免嵌套的 flatMap
结构?请注意,我不想将Either
转换为Validation
。
vavr 中有一个 for comprehension 构造,您可以将其用于您的用例。它可以帮助您将多个 Iterable
、Option
、Try
、Future
或 List
实例转换为另一个 Iterator
、Option
、Try
、Future
或 List
实例,通过将它们(作为它们的笛卡尔积的行)组合成结果值。
在您的情况下,Either
是 右 值上的 Iterable
,您可以使用 For
构造 Iterable
s 构建 String
正确值的 Tuple3
,并通过调用您的副作用代码或 mapping/transforming 以任何方式迭代结果 Iterator
想。您将拥有一个 rich vavr Iterator
,因此它比简单的 JDK Iterator
.
灵活得多
import static io.vavr.API.For;
For(either1, either2, either3)
.yield(Tuple::of)
.forEach(t -> methodRequiringAllInputs(t._1, t._2, t._3));
不过要注意一点:在上面的例子中,yield
的结果是延迟计算的 Iterator
。这意味着您最终需要对其进行迭代才能执行效果,因此 forEach
部分是必不可少的。您不能将产生副作用的代码移到 yield
部分并跳过 forEach
,因为 yield
部分只会在生成的 Iterator
被执行时(懒惰地)执行迭代。
我有几个 Vavr Either,我想为每个 Either 调用一个具有 Right
值的函数。例如:
Either<MyError, String> either1 = ..
Either<MyError, String> either2 = ..
Either<MyError, String> either3 = ..
Either<MyError, String>> methodRequiringAllInputs(String, String, String) {
..
}
我当然可以这样做:
either1.flatMap { value1 ->
either2.flatMap { value2 ->
either3.flatMap { value3 ->
methodRequiringAllInputs(value1, value2, value3);
}
}
}
但这很难看。在其他语言中,您可以只使用诸如 do-notation 或 for comprehensions 之类的东西来展平结构。我知道 Vavr 有一个 Validation 的概念,它是一个允许你做的应用函子:
Validation<MyError, String> validation1 = ..
Validation<MyError, String> validation2 = ..
Validation<MyError, String> validation3 = ..
Validation.combine(validation1, validation2, validation3)
.ap((validationValue1,validationValue2,validationValue3) -> .. );
哪个更好。
我的问题是在 Vavr 中是否存在类似的东西来避免嵌套的 flatMap
结构?请注意,我不想将Either
转换为Validation
。
vavr 中有一个 for comprehension 构造,您可以将其用于您的用例。它可以帮助您将多个 Iterable
、Option
、Try
、Future
或 List
实例转换为另一个 Iterator
、Option
、Try
、Future
或 List
实例,通过将它们(作为它们的笛卡尔积的行)组合成结果值。
在您的情况下,Either
是 右 值上的 Iterable
,您可以使用 For
构造 Iterable
s 构建 String
正确值的 Tuple3
,并通过调用您的副作用代码或 mapping/transforming 以任何方式迭代结果 Iterator
想。您将拥有一个 rich vavr Iterator
,因此它比简单的 JDK Iterator
.
import static io.vavr.API.For;
For(either1, either2, either3)
.yield(Tuple::of)
.forEach(t -> methodRequiringAllInputs(t._1, t._2, t._3));
不过要注意一点:在上面的例子中,yield
的结果是延迟计算的 Iterator
。这意味着您最终需要对其进行迭代才能执行效果,因此 forEach
部分是必不可少的。您不能将产生副作用的代码移到 yield
部分并跳过 forEach
,因为 yield
部分只会在生成的 Iterator
被执行时(懒惰地)执行迭代。