我正在Haskell写一个brainfuck解释器,我想出了一个我认为对程序非常有趣的描述:
data Program m = Instruction (m ()) (Program m)
| Control (m (Program m))
| Halt
Run Code Online (Sandbox Code Playgroud)
但是,将brainfuck程序的文本表示解析为此数据类型是很棘手的.尝试正确解析方括号时会出现问题,因为有一些结点可以使Instruction
循环中的最终内容Control
再次链接到循环.
更多初步信息.有关所有详细信息,请参阅github repo上的此版本.
type TapeM = StateT Tape IO
type TapeP = Program TapeM
type TapeC = Cont TapeP
branch :: Monad m => m Bool -> Program m -> Program m -> Program m
branch cond trueBranch falseBranch =
Control ((\b -> if b then trueBranch else falseBranch) `liftM` cond)
loopControl :: TapeP -> TapeP -> …
Run Code Online (Sandbox Code Playgroud) 我有一个问题,我不知道如何推理.我只是想问一下是否有人可以帮助我解决具体问题,但我突然意识到我可以提出一个更普遍的问题,希望能得到一个更好的一般性理解.希望.所以这里:
当你的程序太懒,通常很明显,因为你最终会遇到像空间泄漏这样的明显问题.我有相反的问题:我的程序太严格了.我想扎 结,并发现某些事情,我试图这样做会以某种方式打败我需要的懒惰.所以我的一般问题是,如何调试不必要的严格性?
为了完整起见,这是我的具体情况:我在RWS
,编写器组件填充地图,阅读器组件观察该地图的最终状态.在我完成填充之前,我不能对这张地图做任何严格的事情.在地图中查找值似乎没有问题,例如:
do
m <- ask
val <- m ! key
doSomething val -- etc.
Run Code Online (Sandbox Code Playgroud)
但是(!)
没有使用error
,我更愿意使用我的monad失败fail
.所以我想做类似以下的事情:
do
m <- ask
maybe
(fail "oh noes")
(doSomething)
(lookup key m)
Run Code Online (Sandbox Code Playgroud)
这导致我的程序<<loop>>
,我不明白.在我看来,这不应该比使用更严格(!)
,但显然我错了......