Scala.Either orElse方法

时间:2013-08-21 08:09:36

标签: scala either

在Scala中使用Either的惯用方法是什么?例如,当使用Option时,如果当前为orElse,我可以使用None方法获取下一个可选值。但是如何以同样的方式使用Either?我没有找到类似orElse的方法来链接Either(并且我知道使用这种方法并不是一个好主意,因为我们丢失了Left值)

修改:实际上,我有一系列if-elseif-elseif-else个表达式,每个表达式都返回RightLeft。我想重构我的代码,使其变得“更具功能性”。我可以将其替换为firstOption orElse secondOption orElse...,如果它是Option,但是如何在Either使用?

3 个答案:

答案 0 :(得分:9)

这方面有很长的discussion。目前正如您所说Either是无偏见的(即左和右被视为相同)。因此,如果调用orElse,则不知道该怎么办?做正确的偏见会解决问题(如Tony Morris所说,这是一个错误)

所以有些黑客是:使用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)。还有一个解决方案是建议的here

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。


更新

发布Scala 2.12后,Either是右偏的,这意味着Right被认为是默认情况下进行操作。如果是Left,则mapflatMap等操作会使Left值保持不变:

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

您可以在Either API上阅读更多内容。

答案 1 :(得分:1)

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)

答案 2 :(得分:0)

最接近的:

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方法。