是否可以通过某些导入获得此功能?
是的,但是通过第三方导入:ScalazMonad
为Either
.
import scalaz._, Scalaz._
scala> for {
| foo <- 1.right[String]
| bar <- "nope".left[Int]
| } yield (foo.toString + bar)
res39: Either[String,java.lang.String] = Left(nope)
现在if
-guard 不是一元操作。因此,如果您尝试使用if
-guard,则会按预期导致编译器错误。
scala> for {
| foo <- 1.right[String]
| if foo > 3
| } yield foo
<console>:18: error: value withFilter is not a member of Either[String,Int]
foo <- 1.right[String]
^
上面使用的便捷方法 -.right
和.left
- 也来自 Scalaz。
编辑:
我错过了你的这个问题。
假设我想为 Either 提供我自己的“monad 实例”,我该怎么做呢?
Scala 推导式for
被简单地转换为.map
, .flatMap
, .withFilter
, 并调用所涉及的对象。(您可以在此处找到完整的翻译方案。)因此,如果某些类没有所需的方法,您可以使用隐式转换将它们添加到类中。.filter
.foreach
下面是一个新的 REPL 会话。
scala> implicit def eitherW[A, B](e: Either[A, B]) = new {
| def map[B1](f: B => B1) = e.right map f
| def flatMap[B1](f: B => Either[A, B1]) = e.right flatMap f
| }
eitherW: [A, B](e: Either[A,B])java.lang.Object{def map[B1](f: B => B1): Product
with Either[A,B1] with Serializable; def flatMap[B1](f: B => Either[A,B1]):
Either[A,B1]}
scala> for {
| foo <- Right(1): Either[String, Int]
| bar <- Left("nope") : Either[String, Int]
| } yield (foo.toString + bar)
res0: Either[String,java.lang.String] = Left(nope)