gpt4 book ai didi

java - 减少其中一个状态抛出异常的简洁方法

转载 作者:行者123 更新时间:2023-11-30 06:19:26 24 4
gpt4 key购买 nike

我有很多这样的:

Validation<String, Foo> a;
Validation<String, Foo> b;
Validation<String, Foo> c;

以下是他们的一些方法:

boolean isValid();
boolean isInvalid(); // === !isValid()
String getError();

现在,我正在尝试这样做:

Stream.of(a, b, c).reduce(
Validation.valid(foo),
(a, b) -> a.isValid() && b.isValid()
? Validation.valid(foo)
: String.join("; ", a.getError(), b.getError())
);

有一个明显的问题,如果只有 a 之一或b是错误的,那么就有一个不必要的; 。但还有一个更严重的问题:getError()如果验证有效则抛出异常。

有没有办法可以编写这个 lambda(或在 io.vavr.control.Validation library 中使用其他内容),而不需要明确所有 4 个案例( a && ba && !b!a && b!a && !b )?

<小时/>

编辑

更清楚地说,我想要的结果是 Validation<String, Foo>到底。我认为它的行为就像一个“单子(monad)”,但我不确定。

最佳答案

我认为您想要实现的目标在Either域中更容易解决。

首先,将 Validation 流转换为 Either 流:

Stream<Either<String, Foo>> eithers = Stream.of(a, b, c)
.map(Validation::toEither);

然后将它们组合起来:

Either<String, Foo> result = Either.sequence(eithers)
.mapLeft(seq -> seq.collect(Collectors.joining("; ")))
.map(combinator); // fill in with combinator function that converts
// a Seq<Foo> into a single Foo

由于您没有指定如何将多个有效的 Foo 对象组合成一个对象,因此我将其保留为开放状态,供您填写上例中的组合器函数。

Either.sequence(...)如果提供的任何一个是左值,或者 Either,则通过返回包含左值序列的 Either.Left 将许多任一值减少为一个。 .Right 包含所有右值的(可能为空)序列,如果所提供的任何一个都不是左值。

更新:

有一个Validation.sequence(...)可以在不转换为任一域的情况下完成此操作的方法(我在创建原始答案时以某种方式错过了这一点 - 感谢您指出):

Validation<Seq<String>, Seq<Foo>> validations = Validation.sequence(
Stream.of(a, b, c)
.map(v -> v.mapError(List::of))
);

Validation<String, Foo> result = validations
.mapError(errors -> errors.collect(Collectors.joining("; ")))
.map(combinator); // fill in with combinator function that converts
// a Seq<Foo> into a single Foo

您说 Foo 实例是相同的,这意味着您可以使用 Seq::head 代替组合器函数。但您需要注意不要使用空的验证序列作为输入,因为在这种情况下,它会导致 Seq::head 抛出 NoSuchElementException

关于java - 减少其中一个状态抛出异常的简洁方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48504309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com