gpt4 book ai didi

haskell - 使用 ContT 的列表迭代器

转载 作者:行者123 更新时间:2023-12-02 13:47:20 25 4
gpt4 key购买 nike

我有一个简单的列表,我想在每个元素之间迭代“yield”并将该元素打印到输出。我正在尝试使用 ContT monad 来执行此操作,但遇到了问题。这是我到目前为止所拥有的:

data K a = Nil | K (a,() -> K a)
listIterator :: (Monad m) => [r] -> m (K r)
listIterator [] = return Nil
listIterator (x:xs) = return (ContT (\k -> K (x,k))) >> listIterator xs

runIterator :: IO ()
runIterator = do
a <- listIterator ([1,2,3] :: [Int])
let loop Nil = liftIO $ print "nil"
loop (K (curr,newI)) =
do
liftIO $ print curr
loop (newI ())
loop a

预期输出是:

1
2
3
nil

我得到的是:

nil

感谢任何帮助!

最佳答案

listIterator (x:xs) = return (ContT (\k -> K (x,k))) >> listIterator xs

不符合你的预期,等式推理

listIterator (x:xs) 
= return (ContT (\k -> K (x,k))) >> listIterator xs
= (return (ContT (\k -> K (x,k)))) >>= \_ -> listIterator xs
= (\_ -> listIterator xs) (ContT (\k -> K (x,k)))
= listIterator xs
<小时/>

我不确定你为什么要使用迭代器。 Haskell 已经很懒惰了,因此这样的迭代模式主要仅在您遇到需要与需求驱动的使用模式良好交互的资源管理问题时使用。而且,您根本不需要延续单子(monad):

与其编写 K 构造函数来获取元组,不如编写更惯用的方式

data K a = Nil | K a (() -> K a)

直观上,listIterator 的类型不使用其一元结构:它只是构造一个值,因此

listIterator ::[r] -> K r
listIterator [] = Nil
listIterator (x:xs) = K x (\_ -> listIterator xs)

现在的生活很琐碎

runIterator :: IO ()
runIterator = do
let a = listIterator ([1,2,3] :: [Int])
loop Nil = liftIO $ print "nil"
loop (K curr newI) =
do
liftIO $ print curr
loop (newI ())
loop a

最好不使用 do 表示法来编写。

关于haskell - 使用 ContT 的列表迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11602953/

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