我正在学习范畴论。我理解 reader monad 的概念,它甚至很容易实现:
case class Reader[DEP, A](g: DEP => A) {
def apply(dep: DEP): A = g(dep)
def map[B](f: A => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
def flatMap[B](f: A => Reader[DEP, B]): Reader[DEP, B] = Reader(dep => f(apply(dep)) apply dep)
}
但是,我在限制某些通用 Monad 接口的情况下实现它时遇到问题,即
trait Monad[A] {
def pure(a: A): Monad[A]
def map[B](f: A => B): Monad[B]
def flatMap[B](f: A => Monad[B]): Monad[B]
}
让我们暂时忘记有一个 applicative 或 functor,让我们把这 3 个方法放在这里。
现在,有了这个接口,我在实现 ReaderMonad 时遇到了问题。map 方法非常简单,但是 pure 和 flatMap 呢?纯阅读器意味着什么?要实现 flatMap,我需要从 A 到 Reader[DEP, B] 的函数,但我有 A => Monad[B],因此无法访问 apply。
case class Reader[DEP, A](g: DEP => A) extends Monad[A] {
def apply(dep: DEP): A = g(dep)
override def pure(a: A): Reader[DEP, A] = Reader(_ => a) // what does it even mean in case of Reader
override def map[B](f: (A) => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
override def flatMap[B](f: (A) => Monad[B]): Reader[DEP, B] = ??? // to implement it, I need f to be (A) => Reader[DEP, B], not (A) => Monad[B]
}
是否可以在scala中以这种方式实现它?我尝试使用自绑定类型,但它也不起作用。我知道像scalaz或cats这样的库使用类型类来实现这些类型,但这只是为了教育目的。