Bry*_*yan 7 monads continuations haskell
我正在做一个需要我写一个小翻译的项目.指令具有简单的树结构,其中一个命令具有停止执行的效果.因此,在下面的示例中,"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 ()
Run Code Online (Sandbox Code Playgroud)
这是我第一次看到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 ()
Run Code Online (Sandbox Code Playgroud)
然后foo bar和baz所有会打印.你需要的是一个转义机制,它允许你中止整个计算并立即返回一个值.这正是callCC提供的.调用命名计算(k在您的代码中)允许您逃离整个计算,而不仅仅是该级别/层.
非常好,我相信,你已经在这里找到了恰当的ContT用例.
| 归档时间: |
|
| 查看次数: |
1069 次 |
| 最近记录: |