Hi Hector,

Hector Guilarte wrote:
I did that already, but it didn't work... Also, since this kind of error would 
be a run time error in my GCL Language, I don't want it to continue executing 
whenever an error is found, that's why I changed it back to just:
evalExpr:: Expr -> Tabla -> Int

Instead of using the Either String Int...

I think you misunderstand something.

If you use (Expr -> Table -> Int), you are announcing:
Whatever happens, I keep executing.

If you use (Expr -> Table -> Either String Int), you are announcing:
I may stop earlier because of some problem.

Since may you want to stop earlier, you should use the second type.


Let's look at a very small example, an interpreter for the following little language:

  data Expression
    = Literal Integer
    | Add Expression Expression
    | Divide Expression Expression

Because of division by zero, an interpreter for this language may fail. So we have two kinds of return values: Sometimes we return a number, and sometimes we return an DivideByZero error. We can reflect that in a datatype:

  data Result
    = Number Integer
    | DivideByZeroError

Now we can write our interpreter:

  eval :: Expression -> Result
  eval (Literal n)
    = Number n

  eval (Add a b)
    = case eval a of
        Number result_of_a
          -> case b of
               Number result_of_b
                 -> Number (result_of_a + result_of_b)

               DivideByZeroError
                 -> DivideByZeroError

        DivideByZeroError
          -> DivideByZeroError


  eval (Add a b)
    = case eval a of
        Number result_of_a
          -> case b of
               Number result_of_b
                 -> if b == 0
                      then DivideByZeroError
                      else Number (result_of_a + result_of_b)

               DivideByZeroError
                 -> DivideByZeroError

        DivideByZeroError
          -> DivideByZeroError


This interpreter will stop as soon as it encounters a division by zero, because we take care to return DivideByZeroError whenever we see a DivideByZeroError in one of the subterms.

So you have to use an appropriate return type (like (Either String Int) or Result), and you have to pattern match on the result of "earlier" parts of your program, and propagate the error.

  Tillmann
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to