【问题标题】:What is difference between those two monad transformers?这两个单子变压器有什么区别?
【发布时间】:2016-04-16 23:50:13
【问题描述】:
我熟悉单子,例如Reader、Error 和 State。然而,变形金刚对我来说很新,因此提出了这个问题。
直观地说,我可以看出以下两个 monad 转换器之间存在差异,但我无法确定它是什么......
ReaderT Env (ErrorT String (StateT Integer Identity)) a
ReaderT Env (StateT Integer (ErrorT String Identity)) a
这两个 monad 转换器有何不同?
【问题讨论】:
标签:
haskell
monads
transformation
【解决方案1】:
为简化起见,仅比较相关部分(并非完全相同):
MaybeT (StateT Integer Identity) a
StateT Integer (MaybeT Identity) a
我们知道(忽略 newtype 抽象)
type MaybeT m a = m (Maybe a)
type StateT s m a = s -> m (a, s)
因此,两个变压器堆栈出来了
MaybeT (Λb. Integer -> (b, Integer)) a
≡ Integer -> (Maybe a, Integer)
和
StateT Integer (Λb. Maybe b) a
≡ Integer -> Maybe (a, Integer)
所以,这些并不完全相同,不同之处在于后者只产生Maybe 内部的状态整数。这意味着,如果MaybeT 在堆栈中向下,则计算必须在您获得Nothing 后立即终止,而如果在顶部使用MaybeT,则State 仍然可以继续进行。
IO 的情况更加严重:一旦遇到异常,您无法可能继续 - 异常只能在 IO 本身中捕获。这就是为什么没有IOT 转换器的原因之一。
【解决方案2】:
ReaderT Env (ErrorT String (StateT Integer Identity)) a
ReaderT Env (StateT Integer (ErrorT String Identity)) a
简而言之,第一个错误仅取决于Env 输入,而第二个允许错误同时取决于Env 和Integer 状态。