考虑State
类型 - 或者至少是简化版本:
newtype State s a = State { runState :: s -> (a, s) }
现在,假设我们要导出StateT
monad 转换器。transformers
定义如下:
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
在这里,m
被放置在函数箭头的右侧,但在元组之外。但是,如果我们不知道正确的答案,我们可能会放在m
其他地方:
newtype StateT s m a = StateT { runStateT :: m (s -> ( a, s)) }
newtype StateT s m a = StateT { runStateT :: s -> (m a, s) }
显然版本transformers
是正确的,但为什么呢?更一般地说,在定义 monad 转换器时,如何知道将“内部”monad 的类型变量放在哪里?更概括地说, comonad 变压器是否有类似的规则?