Search code examples
haskelltype-inferencehugs

Cannot infer instance using evaluator


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.


Solution

  • What eval expects is an argument of a type that eval is defined for. Looking at the signature, it requires an argument of type Expr, either a Val or a Div. eval 4 means that you're passing an Int to the function. For that to work, eval would have to be defined as:

    eval :: Int -> Int
    

    By writing (Val 4), you are invoking one of the data constructors of Expr type, creating a new value of type Expr, which you can pass to eval and make the compiler happy.