(Please forgive me in advance for any formatting errors, as this is the first time I’ve asked a question here.)
I’m working on an interpreter for the While language for class, and I think I have a pretty good handle on the ideas behind it and what I need to do. Some code was provided for us (the eval functions for the Expr type) and we have to implement the eval for the Statement type and the symbol lookup functionality for assignments.
My current problem is that I’m getting type errors while trying to do the above and I’m not sure why.
Here’s the relevant code (note that the While eval is set to = 0 intentionally at the moment):
data Expr = Num Integer
| Var String
| Bin Op Expr Expr deriving Show
data Statement = Assign String Expr
| If Expr Statement Statement
| While Expr Statement
| Compound [Statement] deriving Show
env = [("n",1), ("fact", 1)]
eval (Num x) _ = x
eval (Var v) e = xlookup v e
where xlookup v ((w, x):r) | v==w = x
| otherwise = xlookup v r
eval (Bin op l r) e = kop op (eval l e) (eval r e)
where kop Mul x y = x * y
kop Sub x y = x - y
kop Add x y = x + y
kop Gt x y | x > y = 1
| otherwise = 0
eval (While exp s) e = 0
factorial = (Compound [
(Assign "n" (Num 7)),
(Assign "fact" (Num 1)),
(While (Bin Gt (Var "n") (Num 1))
(Compound [
(Assign "fact" (Bin Mul (Var "fact") (Var "n"))),
(Assign "n" (Bin Sub (Var "n") (Num 1)))
])
)
])
Here’s what I get:
Hugs> :l while.hs
ERROR "while.hs":37 - Type error in function binding
*** Term : eval
*** Type : Statement -> [([Char],Integer)] -> Integer
*** Does not match : Expr -> [([Char],Integer)] -> Integer
Basically, every attempt I make at an eval function for a Statement, Haskell seems to be expecting an Expr instead and I’m not sure why. I’m sure this is a very basic question but unfortunately I’m very new to Haskell and apparently still pretty terrible at it. Thanks for any help.
You either need to make
evala method of a typeclass, which I think is overkill at this point, or make separate eval functions for your Expr and Statement types:The typeclass method would look like: