haskell - Haskell 中定义的 For 循环出现问题

标签 haskell for-loop interpreter

我遇到了同样的问题,但也许我可以提供更多关于我的情况的背景信息,也许这会有所帮助。

使用 typedef 创建解释器:

interp :: Env -> Expr -> M Val

处理这种格式的循环:

for ( var = expr to expr ) ( expr )

数据构造函数定义如下:

data Val =
   ValInt Int
 | ValBool Bool
 | ValFun (Val -> M Val)
 | ValRecFun (Val -> Val -> M Val)
 | ValRef Loc
 | ValNil

扩展环境定义为:

extendEnv :: Identifier -> Val -> Env -> Env
extendEnv var val (Env bs) = Env ((var,val):bs)

这就是我现在的位置:

interp env (For x e1 e2 e3)       = do
                                      (ValInt v1) <- interp env e1
                                      (ValInt v2) <- interp env e2
                                      if (v1 < v2)
                                        then 
                                            let nenv = extendEnv x e1 env in do
                                                interp nenv e3
                                                interp env (For x e1 e2 e3)
                                        else return ValNil

显然,我不想将“e1”传递到for循环的递归调用中,而是将计算的“v1”变量递增......但我不知道如何将其传递到正确的位置“v1”的表达。这是否足以获得一些帮助?:)

*更新*

好的,这是我创建 doLoop 的尝试,它将完成我的循环工作。我觉得它有点过度设计,但我无法弄清楚如何在 doLoop 中调用“env”而不在调用中传递它。

interp env (For x e1 e2 e3)= do
                          (ValInt v1) <- interp env e1
                          (ValInt v2) <- interp env e2
                     return doLoop x v1 v2 env e3

doLoop :: Identifier -> Int -> Int -> Env-> Expr -> M Val
doLoop x v1 v2 env e3 = 
                 if v1 > v2 then return ValNil
                 else
                    let nenv = extendEnv x (ValInt v1) env in
                    interp nenv e3
                    doLoop x (ValInt (v1+1)) v2 nenv e3

更新

我的 For 定义似乎有问题,即:

return doLoop x v1 v2 env e3 

它无法将预期类型 M Val' 与我推断的类型Expr -> M Val' 相匹配。

我在这里犯了一些愚蠢的错误吗?

最佳答案

Obviously, I don't want to pass "e1" into the recursive call of the for loop, but rather the evaluated "v1" variable incremented.... but I can't figure out how to pass it the correct expression of "v1". Is this enough direction to get a little help?:)

您已经在 v1 中获得了变量 e1 的“纯”表示,您只需将 1 添加到 v1 并重新打包即可它。将 makeConstExpr 替换为您用来构造 Expr 的内容。

interp env (For var start end body) = do 
 (ValInt s) <- interp env start
 (ValInt e) <- interp env end 
 if s <= e 
   then
       let envn = extendEnv var (ValInt s) env in do
     interp envn body
     interp env (For var (makeConstExpr (s + 1)) end body) 
   else return ValNil

(我似乎记得最近输入过这个...)

有些人认为最好使用内置函数并制作元解释器来抽象它。由于这是一项任务,因此您最好将其设置为尽可能非元,以增加您对工作力量的理解。

编辑:根据您进行突变的方式,您可能需要在 interp 中传递 nevn 而不是 env env(对于 var (ValInt (s + 1)) 结束体)

关于haskell - Haskell 中定义的 For 循环出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4474306/

相关文章:

c - MPLABx 这个错误是什么意思?

javascript - 我应该支持哪种游戏内脚本语言?

clojure - Lisp解释时 "reader"的任务是什么?

parsing - Trifecta 中的自定义状态

java - 如何以编程方式提取视频帧?

python for 循环

c++ - 我得到一个 "string subscript out of range error"。我不明白为什么

javascript - 有没有最近的 Lua 到 JavaScript 的转换器或解释器?

haskell - 有没有更好的方法来编写 "string contains X"方法?

haskell - 将功能依赖类转换为类型族实例