我需要将一堆返回Either[String, X]
的函数包装成for-comprehension,并且还需要使用一些纯函数转换一些调用的结果,并将这些结果缓存到临时变量中
以下(非常人为的)代码无法编译
1: def someFunc(x: Int): Either[String, Int] = Right(x)
2:
3: def someMath(i: Int): Int = i
4:
5: val z = for {
6: x <- Right("aaaa").right
7: y <- Right((1, x)).right
8: tmp = someMath(y._1)
9: t <- Right(tmp).right
A: l <- someFunc(tmp).right
B: } yield l
C:
D: z
错误:(7,6)value flatMap不是Product with的成员 可以使用scala.util.Either [Nothing,((Int,String),Int)] y进行序列化 &lt; - 右((1,x))。右 ^
如何在for {...}
表达式中定义任意类型的变量(不是Either)?
答案 0 :(得分:0)
在scala 2.12中,Either
是可以使用for
组成的monadic类型,因此以下工作:
val z = for {
x <- Right("aaa")
y <- Right((1, x))
...
}
正如@jdevelop在评论中提到的,这在2.10或2.11
中不起作用如果您的Left
类型是个例外,则Try
是一个不错的选择。如果你需要一个Either
的可移植版本,那么写一个就不难了,就像那样烦人。
答案 1 :(得分:0)
您可以有一个像这样的隐式转换器:
implicit class EitherOps[A,B](val e: Either[A,B]) extends AnyVal {
def flatMap[A1 >: A, B1](f: B => Either[A1, B1]): Either[A1, B1] = e.right.flatMap(f)
def map[B1](f: B => B1): Either[A, B1] = e.right.map(f)
}
使任一权利都像Scala 2.12+中那样有偏见。 您应该仅将其用于Scala 2.11。 这样,您也可以使用与2.12和2.11中相同的全面代码。