7

Either在 Scala 中使用 's 的惯用方式是什么?例如,当使用OptionI时orElse,如果 current 为 ,则可以使用方法获取下一个可选值None。但是如何以Either同样的方式工作呢?我没有找到像orElse 链接 Either's 的方法(而且我知道拥有这种方法并不是一个好主意,因为我们失去了Left价值)

编辑:事实上,我有一个if-elseif-elseif-else表达式序列,每个都返回Rightor Left。我想重构我的代码,让它变得“更实用”。firstOption orElse secondOption orElse...所以我可以用if来替换它Option,但是如何在这里使用Either呢?

4

3 回答 3

10

好吧,对此进行了很长时间的讨论。目前正如你所说Either的是无偏见的(即左和右被视为相同)。orElse因此,如果被调用,不知道该怎么办?让它偏向正确会解决问题(正如托尼莫里斯所说,这是一个错误)

所以一些技巧是:使用 LeftProjection 或 RightProjection。Right Projection具有实用功能 map、flatMap、filter 等)

val a:Either[String, Int]
val b:Either[String, Int]

for{
x <- a.right //returns a RightProjection of a
y <- b.right
} yield (a,b)

a.right.getOrElse(b.right)此处建议的另一种解决方案是:

object Implicits {
    implicit def rightBiasEither[A, B](e: Either[A, B]): Either.RightProjection[A, B] = e.right
  }

import Implicits._
a.getOrElse(b).getOrElse(c)

这样你就可以继续使用它作为 monad。


更新

Post Scala 2.12Either是右偏的,这意味着它Right被假定为默认情况下进行操作。如果是Left,则类似map和的操作flatMap返回Left不变的值:

 def doubled(i: Int) = i * 2
 Right(42).map(doubled) // Right(84)
 Left(42).map(doubled)  // Left(42)

您可以阅读有关Either API 的更多信息。

于 2013-08-21T08:25:17.273 回答
4

开始Scala 2.13,Either#orElse已可用,(在Either中偏右后Scala 2.12):

Right(1) orElse Left(2) // Right(1)
Left(1) orElse Left(2)  // Left(2)
Left(1) orElse Left(2) orElse Right(3) // Right(3)
于 2019-03-28T20:05:41.327 回答
1

最接近的:

Left(1).left.flatMap(_=>Left(2)).left.flatMap(_=>Left(3))
res22: Either[Int, Nothing] = Left(3)

Right(1).left.flatMap(_=>Left(2)).left.flatMap(_=>Left(3))
res23: Either[Int, Int] = Right(1)

如果Try您正在处理Throwable

either1.toTry orElse either2.toTry

是的,在我看来,缺乏的orElse是不一致,因为Either现在 2.12 是正确的,并且有getOrElse方法。

于 2018-03-11T04:54:13.963 回答