开发者

How do I deal with this Haskell difficulty? [closed]

开发者 https://www.devze.com 2023-01-31 13:00 出处:网络
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time,or an extraordinarily narrow situation that is not generally applic
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwid开发者_开发技巧e audience of the internet. For help making this question more broadly applicable, visit the help center. Closed 10 years ago.

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 like VBool in your question. I assume it holds a single value of type Int.
  • 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.

0

精彩评论

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