Search code examples
haskelleval

Haskell: eval :: Ast -> Int


I have an assignment, and there's one question that I just do not understand. What is it that they're asking for? Not sure if this is a SO-fitted question, but I'm in a complete brain freeze, so it would mean a lot if anyone helped!

Question:

Let's consider user-defined data type data Ast = V Int | P Ast Ast | M Ast Ast We imagine that each leaf V x represents the number x, while P and M represent addition and multiplication of their arguments. Program a function

eval :: Ast -> Int

which evaluates such an Ast as an arithmetic expression, e.g.

eval (V 5) = 5
eval (P (V 55) (M (V 2) (V 3))) = 55 + (2 * 3) = 61
eval (M (P (V 12) (V 3)) (M (V 2) (V 5))) = (12 + 3) * (2 * 5) = 150

Solution

  • The nice thing with a language like Haskell is, definitions actually look almost like examples. The ones you gave form literally a syntactically valid definition:

    eval :: Ast -> Int
    eval (V 5) = 5
    eval (P (V 55) (M (V 2) (V 3))) = 55 + (2 * 3)
    eval (M (P (V 12) (V 3)) (M (V 2) (V 5))) = (12 + 3) * (2 * 5)
    

    Only, it is neither minimal nor complete. For instance, eval (V 5) will be ok, but eval (V 6) won't. Solution? Well, don't hard-code the particular case of 5, but instead allow any int value:

    eval (V x) = x
    

    Likewise, you should make clauses that match anything of the form of a sum / product, respectively, not just one particular example expression.

    eval (P l r) = _ + _
    

    To fill in the gaps, you'll need already-evaluated expressions corresponding to l and r. Well, l and r are not evaluated... if only we had a function that takes expressions and gives us their evaluated form...