为什么 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 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 值。
我不明白这行:
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 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 值。