
I've got what's probably a beginner's question, but I'm out of ideas for solving it. It looks like it tripped me up in "Write Yourself a Scheme..." too, since the code there seems like it's arranged so I never ran into it... I've got a couple functions: binop :: (AmbrosiaData -> AmbrosiaData -> AmbrosiaM AmbrosiaData) -> AmbrosiaM () binop operator = do second <- popStack first <- popStack result <- operator first second pushStack result numNumOp :: Num a => (a -> a -> a) -> AmbrosiaData -> AmbrosiaData -> AmbrosiaM AmbrosiaData numNumOp op (Number val1) (Number val2) = return $ Number $ op val1 val2 numNumOp op (Float val1) (Float val2) = return $ Float $ op val1 val2 numNumOp op _ _ = throwError . TypeMismatch $ "Number" the intention being that I can define primitive operations for an interpreter with ("+", binop $ numNumOp (+)). In the Number case, val1 & val2 are Integers, while in the Float case, they're Floats. However, when I try to compile, I get: ./Primitives.hs:82: Cannot unify the type-signature variable `a' with the type `Integer' Expected type: Integer Inferred type: a In the application `op val1 val2' In the second argument of `($)', namely `op val1 val2' This makes no sense to me, since Integer is an instance of Num and op is defined as type Num a => a -> a -> a. Shouldn't the typechecker be able to instantiate 'a' with Integer and give the resulting type Integer -> Integer -> Integer, and then pass the final Integer to Number? Is my understanding of typeclasses off somehow? Any help would be appreciated. Regards, Jonathan