gpt4 book ai didi

haskell - 连续单子(monad)转变

转载 作者:行者123 更新时间:2023-12-04 07:50:20 25 4
gpt4 key购买 nike

在尝试为 ContT monad 转换器建立一些直觉时,我(也许并不奇怪)发现自己很困惑。问题在于 shiftT 操作,它似乎没有做任何有用的事情。

首先是一个简单的例子,说明如何使用它

shiftT $ \famr -> lift $ do
a <- calculateAFromEnvironment
famr a
famr a可以是一些更复杂的表达式,只要它返回一些 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 之上添加任何内容的情况?还是它们只是用来使代码更具可读性?

最佳答案

之后searching githubGurkenglas我发现的建议 this very nice explanationshiftTresetT有用法、动机和语义的例子!

这些功能非常简单。它们在 transformers 中的定义库很简单:

resetT :: (Monad m) => ContT r m r -> ContT r' m r
resetT = lift . evalContT

shiftT :: (Monad m) => ((a -> m r) -> ContT r m r) -> ContT r m a
shiftT f = ContT (evalContT . f)

但哲学和意义远远落后于一些直观的理解。所以我建议你从上面的链接中阅读解释。有时,容易定义的事情实际上可以做一些复杂的事情。

从上面链接的哈巴狗的解释中改编的文档:

shiftT

shiftT is like callCC, except that when you activate the continuation provided by shiftT, it will run to the end of the nearest enclosing resetT, then jump back to just after the point at which you activated the continuation. Note that because control eventually returns to the point after the subcontinuation is activated, you can activate it multiple times in the same block. This is unlike callCC's continuations, which discard the current execution path when activated.

See resetT for an example of how these delimited subcontinuations actually work.

resetT

Create a scope that shiftT's subcontinuations are guaranteed to eventually exit out the end of. Consider this example:

resetT $ do
alfa
bravo
x <- shiftT $ \esc -> do -- note: esc :: m Int, not a ContT
charlie
lift $ esc 1
delta
lift $ esc 2
return 0
zulu x

This will:

  1. Perform alfa

  2. Perform bravo

  3. Perform charlie

  4. Bind x to 1, and thus perform zulu 1

  5. Fall off the end of resetT, and jump back to just after esc 1

  6. Perform delta

  7. Bind x to 2, and thus perform zulu 2

  8. Fall off the end of resetT, and jump back to just after esc 2

  9. Escape from the resetT, causing it to yield 0

Thus, unlike callCC's continuations, these subcontinuations will eventually return to the point after they are activated, after falling off the end of the nearest resetT.

关于haskell - 连续单子(monad)转变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43695653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com