看看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)
此外,有什么意义left和right?
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)
你可以使用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库可能是你的,它有一个名为自己的"是"抽象\/(如描述在这里).
Either不能有 a flatMap,因为Either不是 monad。Haskell 通过偏爱这两种类型中的一种而使其成为 monad,但确实没有理由这样做。Either表示“这可以是两种类型之一”。时期。它没有对这两种类型中的一种给予任何优惠待遇。
如果您Either用于错误报告,那么您确实希望它偏向一侧,但这只是众多用例中的一个,并且将单个特殊用例硬编码为具有糟糕设计味道的通用界面。对于那个用例,您也可以使用Try,这基本上是一个有偏见的Either.
left和right返回的投影Either,这是偏置到一侧。
但是,请注意, 的设计和可用性Either经常被争论,它确实不是好的 API 设计的明灯。这是TryScalaZ\/存在的原因之一。