什么是monad-transformer与monad不同?

时间:2011-02-21 12:58:48

标签: scala haskell functional-programming monads 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]
}

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

<小时/> 修改即可。 考虑以下REPL会话:如果monad变换器以某种方式装饰具有读取器功能的monad(反之亦然)

假设我只想使用 Scalaz 中的replicateM;

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

scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))

现在让我们说,我需要从Option[Int]读取Int值,而不是File

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

那么,我可以对待这个读者,好像它是一个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)
                  ^

呃,不。

道歉,如果这一切看起来都很愚蠢,我只是想了解我File => Option[Int] ReaderT中包裹{{1}}可以带给我的可爱之处。

3 个答案:

答案 0 :(得分:8)

Monad变形金刚用于组合/扩展monad(将一个monad的功能添加到另一个monad)。例如,ReaderT(读者变换器)使给定的monad M具有Reader能力(将monad变换为Reader,保留M的原始特征)。

与此同时,Monad变形金刚是具有bindreturn和其他操作的普通monad。

您可以在 Scalaz 中找到monad变换器的示例 - 例如,ReaderState monad。

答案 1 :(得分:7)

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

E.g。在xmonad窗口管理器中,计算在里面运行:

newtype X a = X (ReaderT XConf (StateT XState IO) a)

即由ReaderState monad组成的IO

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

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

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

一切都开始了:

答案 2 :(得分:1)

我不认为Reader是用于从文件中读取值。很确定它是用于读取配置值。我认为它是全局变量,静态或动态/线程局部变量的替代品(在Common Lisp中称为“特殊变量”,或者有时在Scheme中使用“流体释放”称为fluide变量)。因此,使用Reader / ReaderT而不是访问全局或动态变量,而不是将参数传递到可能需要访问某些配置选项的每个方法中。当一些非常深的代码突然需要访问新的配置选项时,这可能很有用。您可以从main()函数中传递该选项,偷偷访问全局或使用Reader / ReaderT。