单子变换器与身份单子

18

使用带有Identity monad的Monad transformer有什么意义,而不是只使用“标准”版本的transformer?

它是否更加灵活?


“standard”版本是什么意思? - Adrian
你的意思是,“变压器的'标准'版本”是什么?通常,应用于恒等单子上的就是“标准”版本的变压器。 - leftaroundabout
我的意思是 StateT s Identity aState s a,它们在功能上是相同的,对吗? - Matthew H
13
我认为一些标准的monad实际上是定义为对Identity应用transformer版本的别名。这样做可以避免重复编写monad代码。 - Ben
2
那么不会有性能惩罚吗?或者 GHC 能够完全优化掉 Identity monad 吗? - Joachim Breitner
2
newtype 包装和解包通常不会有性能惩罚,因此通常不需要担心。 - Louis Wasserman
2个回答

32

回到 mtl 1.0 的时候,我们都有

newtype State s a = State { runState :: s -> (a, s) }

newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }

然而,这意味着任何需要实现像MonadState这样的实例的人都不得不重复努力。

transformers(以及现已停用的monads-fdmonads-tf)中,Ross Paterson决定采用更简单的方法,仅提供后者并将Identity作为基础模型。

这导致在维护mtl时减少了实现工作量,并消除了实现State模型的两种不同方式。但是,它使mtl内部更难教授,因为您需要立即理解transformers版本,并且没有简化版本作为训练轮。

当旧的mtl被淘汰,monads-fd成为mtl 2.0时,采用现有的transformers保留了这个设计决策。

我个人认为至少要有单独的简单模型以作教学之用,但是站在另一边的人数量远远超过了这些人。


5
我完全同意教学目的。也许我们应该设置一个“monads-teach”包,其中包含原始的简化版本。 - Gabriella Gonzalez

11

来自文档:从计算上讲,使用Identity单子而不是简单地将函数应用于其参数没有任何理由。Identity单子的目的是在单子变换器理论中起到基本作用。任何应用于Identity单子的单子变换器都会生成该单子的非变换器版本。

据我理解,通过应用identity单子从单子变换器获取单子的非变换器版本恰好是identity单子存在的目的。与仅使用非变换器单子相比,并没有优势,但有时必须使用单子变换器,例如当您想要使用的函数需要它时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接