I've started to work through http://www.cs.nott.ac.uk/~pszgmh/monads for a intro on functional programming course. What better way to try and understand stuff than to actually try and test the code.
Alas, on the second page I encounter the following:
data Expr = Val Int | Div Expr Expr
eval :: Expr -> Int
eval (Val n) = n
eval (Div x y) = eval x `div` eval y
Which produces an error when I try to run it. I'm not quite sure why this happens. When I try
eval (Val 4) `div` eval (Val 2)
in the repl-loop, it works just fine, but
eval 4 `div` eval 2
Ends in a type inference error.
When I update my definition to the following:
data Expr = Val Int | Div Expr Expr
eval :: Expr -> Int
eval (Val n) = n
eval (Div x y) = eval (Val x) `div` eval (Val y)
I get a type error in definition. What is wrong with the first definition? The course uses Hugs by the way.
What
evalexpects is an argument of a type thatevalis defined for. Looking at the signature, it requires an argument of typeExpr, either aValor aDiv.eval 4means that you're passing anIntto the function. For that to work,evalwould have to be defined as:By writing
(Val 4), you are invoking one of the data constructors ofExprtype, creating a new value of typeExpr, which you can pass toevaland make the compiler happy.