为什么 flatMap 链在第一个左值处停止但在右值处继续

Why chain of flatMap stops on first Left value but continues on Right values

我不明白这行: Right(1).flatMap(_ => Left(2)).flatMap(_ => Left(3))

Right(1) 传递给 .flatMap(_ => Left(2)。它 returns Left(2) 传递给 .flatMap(_ => Left(3)。它应该返回 Left(3)。但它 returns Left(2).

为什么会这样?

另一个例子是Right(1).flatMap(_ => Right(2)).flatMap(_ => Right(3))

它returns Right(3)(它应该有)。

据我了解,它的工作原理如下: Right(1) 传递给 .flatMap(_ => Right(2))。它 returns Right(2) 传递给 .flatMap(_ => Right(3)。最后 returns Right(3)

Scala fiddle

原因是从 Scala 2.12 开始,Either 是右偏。这意味着当剩下结果时,像 flatMap 这样的操作将停止计算。检查实现以了解它:

def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] =
  this match {
    case Left(value)  => Left(value)
    case Right(value) => f(value)
  }

因此,正如您在 Left 的情况下看到的那样,它使用从中提取的值构造了 Left ,而不应用 f

flatmap 关联 Right。我的意思是它只会对 Right 值进行操作,而不会对 Left 值进行操作。这允许 flatMaps 序列在遇到第一个 Left.

时短路

有关更多示例,请参阅 documentation

由于 Either monad 偏向成功,因此在第一次评估 Left 时平面映射计算链被短路 =12=] 值。造成这种偏见的原因是程序员经常将左侧解释为计算错误的结果,而右侧则意味着计算的成功结果。因此,如果 left 意味着错误,则继续计算错误的链条没有多大意义,因此链条已断开。

请注意,Either monad 过去只是按照惯例有偏见。 Either 的常规右偏是 formalised in Scala 2.12. Some argue Either should be unbiased, for example,

If you use Either for error reporting, then it is true that you want it to be biased to one side, but that is only one use-case of many, and hardcoding a single; special use-case into a general interface smells of bad design. And for that use-case, you might just as well use Try, which is basically a biased Either.

当其他人争论支持一方时,

... with Scala 2.12. it became right-biased, which is IMHO a better design choice, and fits perfectly with other similar sum types from other libraries. For example, it’s very easy now to go from Either to / (scalaz dicjuntion) now that there is no bias mismatch. They are completely isomorphic.

然而,Either 的偏差并不会强制仅“happy/unhappy”的语义,例如,Creating a method which returns one or two parameters 中的要求可以用 Either 来解决side 被解释为 happy/successful 值。