Reader monad的应用实例

时间:2016-01-17 14:41:18

标签: scala monads scalaz applicative

我认为scalaz中的每个monad都有Applicative个实例。例如,我可以ApplicativeBuilder使用Option,如下所示:

scala> (1.some |@| 2.some) {_ + _}
res1: Option[Int] = Some(3)

现在我想对Reader

做同样的事情
scala> type IntReader[A] = Reader[Int, A]
defined type alias IntReader

scala> val r1: IntReader[Int] = Reader {x: Int => x + 1 }
r1: IntReader[Int] = Reader(<function1>)

scala> val r2: IntReader[Int] = Reader {x: Int => x + 2 }
r2: IntReader[Int] = Reader(<function1>)

scala> (r1 |@| r2) {_ + _}
<console>:64: error: value |@| is not a member of IntReader[Int]
          (r1 |@| r2) {_ + _}

为什么上面的代码不能编译?

1 个答案:

答案 0 :(得分:1)

为了完整起见:Applicative实例可用,没有导入:

scala> type IntReader[A] = scalaz.Reader[Int, A]
defined type alias IntReader

scala> scalaz.Applicative[IntReader]
res0: scalaz.Applicative[IntReader] = scalaz.KleisliInstances3$$anon$3@f979171

但是如果您想使用|@|语法,则需要导入scalaz.syntax.apply._

scala> import scalaz.syntax.apply._
import scalaz.syntax.apply._

scala> val r1: IntReader[Int] = scalaz.Reader((x: Int) => x + 1)
r1: IntReader[Int] = Kleisli(<function1>)

scala> val r2: IntReader[Int] = scalaz.Reader((x: Int) => x + 2)
r2: IntReader[Int] = Kleisli(<function1>)

scala> (r1 |@| r2) { _ + _ }
res1: IntReader[Int] = Kleisli(<function1>)

这是因为|@|不是Reader上的一种方法 - 它是由ApplyOps浓缩类提供的。