开发者

Problem With Defined For Loop in Haskell

I have come across the same problem, but m开发者_运维技巧aybe I can give a little more context in what is going on for my situation and maybe that can help.

Creating an interpreter with typedef:

interp :: Env -> Expr -> M Val

that handles for loops in this format:

for ( var = expr to expr ) ( expr )

Data constructor defined as the following:

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

And an extended environment defined as:

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

Here's where I am:

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

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?:)

*UPDATE*

Ok, here's my attempt at creating the doLoop that will do my looping work. I feel as if it is a little over-engineered, but I could not figure out how to call the "env" in doLoop without passing it in the call.

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

UPDATE

It seems to be having a problem with my For definition, namely:

return doLoop x v1 v2 env e3 

It can't match the expected type M Val' against my inferred typeExpr -> M Val'.

Am I making some silly error here?


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?:)

You've already got the 'pure' representation of the variable e1 in v1, you can simply add 1 to v1 and repack it. Replace makeConstExpr with whatever it is you use to construct an 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

(I seem to recall typing this recently...)

Some would argue that it's better to abstract this using built in functions and making a meta-interpreter. As this is an assignment, you're probably better off making it as non-meta as possible to increase your understanding of the forces at work.

Edit: Depending on how you're doing your mutation, you may want to pass nevn instead of env in interp env (For var (ValInt (s + 1)) end body).


I think you're almost there. Take a look at this (working with Ints directly, packing them into Vals when appropriate, fixed a little scoping issue with parens, and only passing env in the recursive call):

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 env e3
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜