作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在做一个需要我编写一个小型解释器的项目。这些指令具有简单的树形结构,其中一个命令具有暂停执行的效果。所以在下面的例子中,“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
bar
和
baz
一切都会打印出来的。您需要的是一种转义机制,它允许您中止整个计算并立即返回一个值。这正是
callCC
提供。调用命名计算(代码中的
k
)可以让您逃离整个计算,而不仅仅是那个级别/层。
关于haskell - 这是对 ContT 的适当使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44877444/
这段代码在 Java 中的等价物是什么?我放了一部分,我对 I/O 部分感兴趣: int fd = open(FILE_NAME, O_WRONLY); int ret = 0; if (fd =
我正在尝试将维度为 d1,d2,d3 的张量 M[a1,a2,a3] reshape 为维度为 d2, d1*d3 的矩阵 M[a2,a1*a3]。我试过 M.reshape(d2,d1*d3) 但是
我是一名优秀的程序员,十分优秀!