如果警卫抛出错误的理解

时间:2013-09-23 20:38:46

标签: scala monads for-comprehension either

当我以这种方式使用if guard进行理解时,我收到一个错误。

代码:

for {
  foo <- Left[String,String]("teststring").right
  bar <- Right[String,String]("teststring").right if (foo==bar)
} yield (bar)

错误:

error: type mismatch;
 found   : Option[scala.util.Either[Nothing,String]]
 required: scala.util.Either[?,?]
                bar <- Right[String,String]("teststring").right if (foo==bar)
                    ^

2 个答案:

答案 0 :(得分:0)

这是我为解决上述错误而采取的措施。我也将if-guard移到后来的过程中。

val result = for {
  foo <- Right[String,String]("teststring").right
  bar <- Right[String,String]("teststring").right
} yield (foo, bar)

result fold (
  ex => Left("Operation failed with " + ex),
  v => v match { 
    case (x,y) =>
        if (x == y) Right(x)
        else Left("value is different")
  } 
)

答案 1 :(得分:0)

由于for - 理解need to be of the same type中所有语句的类型以及if (foo == bar)过滤器表达式使最后一个表达式成为最后一个表达式,因此您无法执行您要执行的操作Option[Either[?,?]]代替Either[?,?]

解决此问题的一种方法是将表达式转化为一系列flatMapmapfilter表达式。

另一种方法是丢失左边的两个,只需在RightProjection上使用toOption方法,即:

for {
  foo <- Left[String,String]("left").right.toOption
  bar <- Right[String,String]("right").right.toOption if (foo == bar)
} yield (foo)