0

当我以这种方式使用 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)
                    ^
4

2 回答 2

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")
  } 
)
于 2013-09-23T21:12:39.710 回答
0

你不能做你想做的事情,因为for-comprehension中的所有语句的类型都必须是相同的 type,并且if (foo == bar)过滤器表达式使最后一个表达式成为 anOption[Either[?,?]]而不是Either[?,?]

解决此问题的一种方法是将表达式脱糖为一系列flatMap,mapfilter表达式。

另一种方法是丢失任何一个的左侧,只需使用toOptionRightProjection 上的方法,即:

for {
  foo <- Left[String,String]("left").right.toOption
  bar <- Right[String,String]("right").right.toOption if (foo == bar)
} yield (foo)
于 2013-09-23T21:13:48.443 回答