在尝试为 ContT monad 转换器建立一些直觉时,我(也许并不奇怪)发现自己很困惑。问题在于 shiftT 操作,它似乎没有做任何有用的事情。
首先是一个简单的例子,说明如何使用它
shiftT $ \famr -> lift $ do
a <- calculateAFromEnvironment
famr a
famr a
可能是一些更复杂的表达式,只要它返回 some m r
。现在试图解释我的直觉 shiftT 没有添加任何东西:
-- inline shiftT
ContT (\f2 -> evalContT ((\f1 -> lift (do
a <- calculateAFromEnvironment
f1 a)) f2))
-- beta reduction
ContT (\f2 -> evalContT (lift (do
a <- calculateAFromEnvironment
f2 a)))
-- inline evalConT
ContT (\f2 -> runContT (lift (do
a <- calculateAFromEnvironment
f2 a)) return)
-- inline lift
ContT (\f2 -> runContT (ContT (\f3 -> (do
a <- calculateAFromEnvironment
f2 a) >>= f3)) return)
-- apply runConT
ContT (\f2 -> (\f3 -> (do
a <- calculateAFromEnvironment
f2 a) >>= f3) return)
-- beta reduce
ContT (\f2 -> (do
a <- calculateAFromEnvironment
f2 a) >>= return)
-- (>>= return) is identity
ContT $ \f2 -> do
a <- calculateAFromEnvironment
f2 a
事实证明,我们可以直接构建 ContT。
提问时间:是否存在 shift/shiftT 在 cont/ContT 之上添加任何内容的情况?还是它们只是用来使代码更具可读性?