我正在玩scalaz
的monad变形金刚。我正在试图将一个Writer与底层的Id
monad堆叠在一起。为了组合它们,我使用了MonadReader
和MonadWriter
类型类。如何在scalaz中堆叠ReaderT和WriterT变换器?
我设法编译和运行下面的代码示例而不作家(即与Reader
单子,即ReaderT[Id.Id, String, A]
)。当添加WriterT
到堆栈中,我得到的编译错误:
Gist.scala:10: could not find implicit value for parameter F: scalaz.MonadReader[Gist.R,String]
val MR = MonadReader[R, String]
^
我怎样才能获得的MonadReader
实例为我的变压器栈?我必须使用ReaderWriterStateT
还是有另一种方式?
全码:
import scalaz.{Id, MonadListen, MonadReader, ReaderT, WriterT}
object Gist {
import scalaz.std.list._
import scalaz.syntax.monad._
type P[A] = ReaderT[Id.Id, String, A]
type R[A] = WriterT[P, List[String], A]
val MR = MonadReader[R, String]
val MW = MonadListen[R, List[String]]
def apply: R[String] = MR.ask >>= { greeting =>
MW.tell(List(s"greeting $greeting")) >>= { _ =>
MW.point(s"Hello $greeting")
}
}
}
就像一个魅力。为了教学目的,你能想到另一个没有'scalaz'实现的变压器栈/类型组合,所以我可以练习编写我自己的实现吗? – mgryszko
@mgryszko你可以看到Haskell的mtl [here](https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Reader-Class.html)-'StateT'的列表, 'ListT','ContT','EitherT','IdT'等都是不错的选择。 –