【发布时间】:2015-01-20 13:09:34
【问题描述】:
ContT 的绑定策略忽略了内部 monad,实际上代码与Cont 相同。
按照其他 Monad Transformers 的类比,我会以这种方式实现它:
return x = ContT ($ (return x))
(>>=) x f = ContT (\k -> runContT x ((=<<) (\a -> runContT (f a) k)))
那么例如这个表达式:
do
x1 <- ContT (\k -> k [1, 2])
x2 <- ContT (\k -> k [10, 20])
return ((+) x1 x2)
将导致[11, 21, 12, 22]
我的问题是这个设计决定背后的原因是什么?为什么它是这样实现的,这使得它与其他 Monad Transformer 非常不同,注意 functor 实例是:
fmap f m = ContT $ \c -> runContT m (c . f)
而不是:
fmap f m = ContT $ runCont $ (fmap . fmap) f (Cont (runContT m))
这与其他 Monad Transformers 或多或少相同,但当前的实现似乎打破了函子组合,我的意思是,由于 monad 不会自动组合,我们可能会讨论不同的绑定策略,但对于函子和应用程序应该总是一样的,而这里似乎完全不同。获取一些代表更多用例的代码是否可行?
即使IdentityT 也是如此,但我读到Cont 的绑定策略实际上与Identity 的绑定策略相同,那么ContT 和IdentityT 呢?
【问题讨论】:
标签: haskell monad-transformers