使用带有 Identity monad 的 Monad 转换器而不是仅仅使用“标准”版本的转换器有什么意义?
是不是更灵活?
回到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-fd
and monads-tf
)中,Ross Paterson 决定使用更简单的方法,只提供后者并Identity
用作基本 monad。
这减少了维护 monad 的实现工作,并消除了实现monadmtl
有两种不同方法的事实。State
然而,它确实使内部结构mtl
更难教授,因为您需要从一开始就理解这些transformers
版本,而不是将简化版本作为训练轮。
当旧版本mtl
退役并monads-fd
成为mtl
2.0 时,使用现有的transformers
这个设计决定被继承下来。
我个人喜欢至少将单独的简单单子用于教学目的,但在辩论的另一边有更多的人。
来自文档:在计算上,没有理由使用 Identity monad 而不是简单地将函数应用于其参数的简单得多的行为。Identity monad 的目的是它在 monad 转换器理论中的基本作用。任何应用于 Identity monad 的 monad 转换器都会产生该 monad 的非转换器版本。
据我了解,通过应用身份单子从单子变压器中获取单子的非变压器版本正是身份单子的用途。与仅使用非变压器 monad 相比没有任何优势,但有时您必须使用 monad 变压器,例如当您想要使用的功能需要它时。