Scala的要么没有'flatMap`和Either.left/.right的含义

Kev*_*ith 2 haskell scala

看看Haskell的EitherMonad,有一个>>=功能.

Prelude Map> let add100 = \x -> Right (x+100 :: Int)

Prelude Map> x
Right 5
Prelude Map> x >>= add100
Right 105

Prelude Map> let y = Left "..." :: Either String Int
Prelude Map> y >>= add100
Left "..."
Run Code Online (Sandbox Code Playgroud)

但是,为什么Scala Either[A,B]没有flatMap,即相当于>>=函数?

scala> e
res5: Either[String,Int] = Right(1)

scala> e.
asInstanceOf   fold           isInstanceOf   isLeft         isRight
joinLeft       joinRight      left           right          swap
toString
Run Code Online (Sandbox Code Playgroud)

此外,有什么意义leftright

scala> e.left
res6: scala.util.Either.LeftProjection[String,Int] = LeftProjection(Right(1))

scala> e.right
res7: scala.util.Either.RightProjection[String,Int] = RightProjection(Right(1))
Run Code Online (Sandbox Code Playgroud)

0__*_*0__ 5

你可以使用fold哪个需要两个函数,一个用于左边,一个用于右边,或者使用right投影视图:

val e: Either[String, Int] = Right(5)

def add100(i: Int): Either[String, Int] = Right(i + 100)

e.fold(identity, add100)  // Right(105)
e.right.flatMap(add100)   // Right(105)
Run Code Online (Sandbox Code Playgroud)

因此,投影视图允许您将Either实例视为将通过左或右类型映射的内容.这在Either scala-doc帮助文件中有解释.


如果您熟悉哈斯克尔,该ScalaZ库可能是你的,它有一个名为自己的"是"抽象\/(如描述在这里).


Jör*_*tag 5

Either不能有 a flatMap,因为Either不是 monad。Haskell 通过偏爱这两种类型中的一种而使其成为 monad,但确实没有理由这样做。Either表示“这可以是两种类型之一”。时期。它没有对这两种类型中的一种给予任何优惠待遇。

如果您Either用于错误报告,那么您确实希望它偏向一侧,但这只是众多用例中的一个,并且将单个特殊用例硬编码为具有糟糕设计味道的通用界面。对于那个用例,您也可以使用Try,这基本上是一个有偏见的Either.

leftright返回的投影Either,这偏置到一侧。

但是,请注意, 的设计和可用性Either经常被争论,它确实不是好的 API 设计的明灯。这是TryScalaZ\/存在的原因之一。

  • @KevinMeredith:“favor”意味着`return` 将只返回右侧,而`>>=` 将简单地绑定右侧并忽略左侧或不变地通过它。这意味着右侧比左侧更受青睐,我们通常说它是“偏右”。但是没有真正的理由这样做,*除非*你使用`Either`来表示错误并且你认为`Right`是成功的。但是`Either`还有其他用途,即使你用它来处理错误,那么把错误放在右边,成功放在左边同样有效。 (3认同)