我正在为我的学校项目开发虚拟堆栈机。一切工作正常,但这就是我作为程序运行的控制功能所拥有的:
run :: Program -> SubprogramDir -> Memory -> ComputerStack -> Input -> Output -> Output
run EOP _ _ _ _ out = out
run (lbl `Marks` prg) dir mem stack inp out = run prg dir mem stack inp out
run (ins `Then` prg) dir mem stack inp out =
case ins of
(TA addr) -> (run prg dir mem (Stack.push (Left addr) stack) inp out)
(TV val) -> (run prg dir mem (Stack.push (Right val) stack) inp out)
DR -> (dr prg dir mem stack inp out)
ST -> (st prg dir mem stack inp out)
WR -> (wr prg dir mem stack inp out)
RD -> (rd prg dir mem stack inp out)
AD -> (mathAction (+) prg dir mem stack inp out)
SB -> (mathAction (-) prg dir mem stack inp out)
MT -> (mathAction (*) prg dir mem stack inp out)
DI -> (mathAction (div) prg dir mem stack inp out)
(JU lbl) -> (ju lbl prg dir mem stack inp out)
(JZ lbl) -> (jz lbl prg dir mem stack inp out)
这个dir mem stack inp out
在各处不断重复,看起来很糟糕。有没有一种方法可以将其集中到一个元组中,然后将其传递给其他函数?或者还有其他更好的写法吗?
最佳答案
您可以定义一个辅助调用
函数
run (ins `Then` prg) dir mem stack inp out =
let call k = k prg dir mem stack inp out
in case ins of
TA addr -> (run prg dir mem (Stack.push (Left addr) stack) inp out)
TV val -> (run prg dir mem (Stack.push (Right val) stack) inp out)
DR -> call dr
ST -> call st
WR -> call wr
RD -> call rd
AD -> call $ mathAction (+)
SB -> call $ mathAction (-)
MT -> call $ mathAction (*)
DI -> call $ mathAction (div)
JU lbl -> call $ ju lbl
JZ lbl -> call $ jz lbl
不过,将所有公共(public)状态变量封装在一个数据类型中似乎更合适。通常,这种执行状态被称为抽象机的“配置”。例如,
data Config = Config SubprogramDir Memory ComputerStack Input Output
也可以将其变成一条记录。
关于Haskell:以良好的方式命名多个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49386033/