How do I deal with this Haskell difficulty? [closed]
I'm a new in Haskell and i studied by myself, I'm running program but I don't understand for loop to much. In my program I did While loop,and I'm going to show my work for both but I need explain someone explain for loop how to do this sentence which i made
(let x = ref 0 in ( for (i=1 to 10 )(x:=deref x+i)));deref x )
. There is some variable I use
i can show it to you guys if you want.
I did While loop like this and it works
interp env (While b1 b2) = do
c1 <- interp env b1
case c1 of
(VBool True) -> do
interp env b2
interp env (While b1 b2)
(VBool False) -> return VNil
However, my work for loop is
interp env ( For s a1 a2 a3)= do
v1 <- interp env a1
v2 <- interp env a2
if (v1<v2 ) then do
x <- interp env a1
let env' = extendEnv x e1 env
interp env' a3
else return VNil
but is not working, Please can you explain what's wrong?
I am making the following assumptions in this answer, as not enough information is given to answer properly:
- You have a
VInt
data constructor much likeVBool
in your question. I assume it holds a single value of typeInt
. extendEnv
takes three parameters. This first is a variable ID (of unknown type), the second is the expression to bind it to (or value if this language isn't lazy, of unknown type), the third is the environment you are extending (of, surprise surprise, unknown type).- The input AST has been type checked, so I'm not handling type errors.
Code:
interp env (For var start end body) = do
(VInt s) <- interp env start
(VInt e) <- interp env end
if s < e
then
let nenv = extendEnv var start env in do
interp nenv body
interp nenv (For var (VInt (s - 1)) end body) -- Maybe only env here.
else return VNil
I have come across the same problem, but maybe 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?:)
I think it's impossible to state what's wrong with your for loop using only the code you've provided (type error?). However, if you really insist on mutable state, I would write your for loop
(let x = ref 0 in ( for (i=1 to 10 )(x:=deref x+i)));deref x )
as
import Control.Monad.State
forloop = snd $ runState (forM_ [1..10] incr) 0
incr n = modify (+n)
I probably wouldn't bother trying to abstract any further than this.
精彩评论