这两个monad变压器有什么区别?

What is difference between those two monad transformers?

我熟悉 monad,例如ReaderErrorState。然而,变形金刚对我来说非常陌生,因此提出了这个问题。

凭直觉,我可以看出以下两个 monad 转换器之间存在差异,但我不能完全确定它是什么...

ReaderT Env (ErrorT String (StateT Integer Identity)) a

ReaderT Env (StateT Integer (ErrorT String Identity)) a

这两个 monad 转换器有何不同?

为简化起见,仅比较相关部分(并非完全相同):

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 变压器的原因之一。

ReaderT Env (ErrorT String (StateT Integer Identity)) a
ReaderT Env (StateT Integer (ErrorT String Identity)) a

简而言之,第一个错误仅取决于 Env 输入,而第二个允许错误同时取决于 EnvInteger 状态。