【发布时间】:2014-06-28 22:26:39
【问题描述】:
我有一些评估原始程序的代码。程序是一个语句列表(表达式、块、返回语句)。评估结果是最后评估的表达式。评估者还应正确对待return 语句(即在第一次出现return 后停止评估)。
为了实现这个逻辑,我传递了特殊的回调函数 (NextStep),它在当前语句之后进行下一步评估。处理return语句时不调用下一步:
data Statement =
Expr Int
| Block [Statement]
| Return Int
deriving (Show, Eq)
data Value =
Undefined
| Value Int
deriving (Show, Eq)
type NextStep = Value -> Value
evalStmt :: Statement -> NextStep -> Value
evalStmt (Expr val) next =
let res = Value val
in next res
evalStmt (Block stmts) next = evalBlock stmts next
evalStmt (Return val) next = Value val
evalBlock :: [Statement] -> NextStep -> Value
evalBlock [] next = next Undefined
evalBlock [st] next = evalStmt st next
evalBlock (st:rest) next = evalStmt st $ \ _ -> evalBlock rest next
evalProgram stmts = evalBlock stmts id
prog1 = [Expr 1, Block [Return 3, Expr 2], Expr 4]
evalProg1 = evalProgram prog1 -- result will be Value 3
问题是如何用 continuation monad 重写这段代码?我想摆脱在evalStmt 和evalBlock 函数中显式传递的NextStep 回调。有可能吗?
【问题讨论】:
标签: haskell continuations continuation-passing