什么是monad-transformer与monad不同?

oxb*_*kes 22 monads haskell functional-programming scala scalaz

这个问题说明了一切,真的.我知道(Scala)Monad看起来像这样:

trait Monad[M[_]] {
  def pure[A](a : A) : M[A]
  def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}
Run Code Online (Sandbox Code Playgroud)

Monad Transformer是什么样的?它们用于什么?


编辑.考虑以下REPL会话:如果monad变换器以某种方式装饰具有读取器功能的monad(反之亦然)

比方说,我只是想用replicateMScalaz ;

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))
Run Code Online (Sandbox Code Playgroud)

现在让我们说,而不是有一个Option[Int],我需要读取一个IntFile:

scala> val f = (_ : java.io.File) => some(1)
f: (java.io.File) => Option[Int] = <function1>
Run Code Online (Sandbox Code Playgroud)

所以,我可以对待这个读者,好像它是一个Monad?

scala> ReaderT(f).replicateM[List](2)
<console>:16: error: value replicateM is not a member of scalaz.ReaderT[Option,java.io.File,Int]
       ReaderT(f).replicateM[List](2)
                  ^
Run Code Online (Sandbox Code Playgroud)

呃,不.

如果道歉这一切似乎愚蠢的,我只是想了解什么可爱善良我的包裹File => Option[Int]ReaderT实际上可以给我买.

Vas*_*iuk 8

Monad变形金刚用于组合/扩展monad(将一个monad的功能添加到另一个monad).例如,ReaderT(Reader Transformer)丰富了给定monad MReader功能(将monad转换为Reader保留原始特征M).

与此同时,单子变压器是正常的单子有bind,return和其他操作.

您可以在Scalaz中找到monad变换器的示例 - 例如,用于ReaderState monads.

  • 你能给我一个'ReaderT`的实用例子吗?习惯于命令式编程,它很容易*看一个类型来弄清楚如何使用它.好吧,无论如何,这对我来说. (2认同)

Don*_*art 7

Monad变换器是类型函数,当应用于monad类型时,生成一个新的monad,它结合了两个组件的行为.

例如,在xmonad窗口管理器中,计算在内部运行:

newtype X a = X (ReaderT XConf (StateT XState IO) a)
Run Code Online (Sandbox Code Playgroud)

也就是说,Reader由a StateIOmonad组成.

  • Reader 允许访问只读内存
  • State 提供了一种读写状态
  • IO 允许任意外部效果

请注意,monad变换因此是更高级别的类型.它们采用monadic类型(* -> *),并产生一种新类型.

与往常一样,Haskell wiki有一些有用的内容:

一切都开始了: