gpt4 book ai didi

haskell - 这是对 ContT 的适当使用吗?

转载 作者:行者123 更新时间:2023-12-04 11:34:15 24 4
gpt4 key购买 nike

我正在做一个需要我编写一个小型解释器的项目。这些指令具有简单的树形结构,其中一个命令具有暂停执行的效果。所以在下面的例子中,“baz”永远不会被打印出来。

import Control.Monad.Cont

data Instruction = Print String | Halt | Block [Instruction]
deriving (Eq, Show)

instructions =
[ Print "foo"
, Block
[ Print "bar"
, Halt
]
, Print "baz"
]

main :: IO ()
main = runContT (callCC $ interpret instructions)
(const $ pure ())

interpret [] k = pure ()
interpret (a:as) k = case a of
Print str -> liftIO (putStrLn str) >> interpret as k
Block ins -> interpret ins k >> interpret as k
Halt -> k ()

这是我第一次看到 ContT 的潜在用途。在我的一个项目中。我想知道这是否适合使用它,或者是否有一个更简单的解决方案我可能会忽略。

最佳答案

是的,这看起来正是 Control.Monad.Cont 的用例。是合适的。

您几乎肯定知道这一点,但对于其他读者来说,如果您写了 interpret,则值得一提。所以它是一个从指令列表到 IO () 的函数像这样:

main :: IO ()
main = interpret instructions

interpret :: [Instruction] -> IO ()
interpret [] = pure ()
interpret (a:as) = case a of
Print str -> putStrLn str >> interpret as
Block ins -> interpret ins >> interpret as
Halt -> pure ()

然后 foo barbaz一切都会打印出来的。您需要的是一种转义机制,它允许您中止整个计算并立即返回一个值。这正是 callCC提供。调用命名计算(代码中的 k)可以让您逃离整个计算,而不仅仅是那个级别/层。

干得好,我相信你已经在这里找到了适合 ContT 的用例。

关于haskell - 这是对 ContT 的适当使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44877444/

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