gpt4 book ai didi

haskell - 理解 Haskell callCC 例子

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

我无法理解以前 question 的答案.我希望对以下内容的解释能够澄清事情。以下示例来自 fpcomplete

import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont

main = flip runContT return $ do
lift $ putStrLn "alpha"
(k, num) <- callCC $ \k -> let f x = k (f, x)
in return (f, 0)
lift $ putStrLn "beta"
lift $ putStrLn "gamma"
if num < 5
then k (num + 1) >> return ()
else lift $ print num

输出是
alpha
beta
gamma
beta
gamma
beta
gamma
beta
gamma
beta
gamma
beta
gamma
5

我想我明白这个例子是如何工作的,但为什么有必要有一个 let callCC 中的表达式“返回”延续,以便以后可以使用。所以我尝试通过以下更简单的示例并对其进行修改来直接返回延续。
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont

main = flip runContT return $ do
lift $ putStrLn "alpha"
callCC $ \k -> do
k ()
lift $ putStrLn "uh oh..."
lift $ putStrLn "beta"
lift $ putStrLn "gamma"

这打印
alpha
beta
gamma

我将其修改为以下
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont

main = flip runContT return $ do
lift $ putStrLn "alpha"
f <- callCC $ \k -> do
lift $ putStrLn "uh oh..."
return k
lift $ putStrLn "beta"
lift $ putStrLn "gamma"

想法是继续将返回为 f并且在我希望打印的这个测试示例中未使用
uh oh...
beta
gamma

但是这个例子不能编译,为什么不能这样做呢?

编辑 :考虑Scheme中的类似例子。据我所知,Scheme 不会有问题,对吗?但是为什么呢?

最佳答案

正如其他人所写的那样,最后一个示例由于无限类型而没有进行类型检查。

@augustss 提出了另一种解决此问题的方法:

You can also make a newtype to wrap the infinite (equi-)recursive type into a (iso-)recursive newtype. – augustss Dec 12 '13 at 12:50



这是我的看法:
import Control.Monad.Trans.Cont
import Control.Monad.Trans.Class

data Mu t = In { out :: t (Mu t) }

newtype C' b a = C' { unC' :: a -> b }
type C b = Mu (C' b)

unfold = unC' . out
fold = In . C'

setjmp = callCC $ (\c -> return $ fold c)
jump l = unfold l l

test :: ContT () IO ()
test = do
lift $ putStrLn "Start"
l <- setjmp
lift $ putStrLn "x"
jump l

main = runContT test return

我认为这就是@augustss 的想法。

关于haskell - 理解 Haskell callCC 例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20536700/

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