Scala 单子变压器与单子变压器的区别是什么?

Scala 单子变压器与单子变压器的区别是什么?,scala,haskell,functional-programming,monads,scalaz,Scala,Haskell,Functional Programming,Monads,Scalaz,这个问题说明了一切,真的。我知道(Scala)单子是这样的: trait Monad[M[_]] { def pure[A](a : A) : M[A] def bind[A, B](ma : M[A], f : A => M[B]) : M[B] } Monad转换器是什么样子的?它们是用来干什么的 编辑。考虑下面的RePL会话:如果一个Mad AD以某种方式装饰一个具有读写能力的单元格(反之亦然) 假设我只想使用replicitemfromScalaz scala>

这个问题说明了一切,真的。我知道(Scala)单子是这样的:

trait Monad[M[_]] {
  def pure[A](a : A) : M[A]
  def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}
Monad转换器是什么样子的?它们是用来干什么的


编辑。考虑下面的RePL会话:如果一个Mad AD以某种方式装饰一个具有读写能力的单元格(反之亦然)

假设我只想使用
replicitem
fromScalaz

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

scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))
现在让我们假设,我需要从
文件中读取
Int
值,而不是使用
选项[Int]

scala> val f = (_ : java.io.File) => some(1)
f: (java.io.File) => Option[Int] = <function1>
scala>valf=(quo:java.io.File)=>some(1)
f:(java.io.File)=>Option[Int]=
所以,我可以把这个读者当作一个单子

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)
                  ^
scala>ReaderT(f).replicateM[List](2)
:16:错误:value replicItem不是scalaz.ReaderT[Option,java.io.File,Int]的成员
ReaderT(f).replicItem[列表](2)
^
呃,不


抱歉,如果这一切看起来都很愚蠢,我只是想了解在
ReaderT
中包装
File=>选项[Int]
能给我带来什么好处。

单子转换器用于组合/扩展单子(将一个单子的功能添加到另一个单子)。例如,
ReaderT
(读卡器转换器)使用
Reader
功能丰富了给定的monad
M
(将给定的monad转换为保留
M
原始功能的读卡器)

同时,Monad转换器是具有
绑定
返回
和其他操作的普通Monad


您可以在Scalaz中找到monad转换器的示例,例如for和monad。

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

Monad transformers是类型函数,当应用于Monad类型时,会生成一个新的Monad,它结合了两个组件的行为

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

newtype X a = X (ReaderT XConf (StateT XState IO) a)
也就是说,由
状态
IO
单子组成的
读取器

  • 读卡器
    提供对只读存储器的访问
  • State
    提供一种读写状态
  • IO
    允许任意外部效果
请注意,monad转换因此是更高级别的类型。它们采用一元类型(
*->*
),并产生一种新的类型

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

这一切从哪里开始:


@Vasil-这就是为什么我用scala标记这个问题。有很多scala人不理解Haskell。@oxbow_lakes,但那你为什么接受Haskell的回答?你能给我一个
ReaderT
的实际例子吗?由于习惯了命令式编程,查看一个类型并不能很容易地找出它的用法。无论如何,这是我的问题。我用一个例子修改了这个问题,将函数
File=>Option[Int]
包装在
ReaderT
中。根据Scalaz的说法,我仍然对如何使用我闪亮的新的
ReaderT
感到困惑,a
ReaderT
只是封装了一个函数
a=>m[B]
。在您的例子中,
A
可能是
MyGlobalParams
,而在我的示例中,它是一个
文件
。不过,我还是不明白这到底能给我带来什么。