Haskell: Operations on Double and Int give error “couldn't match expected type”Collection of common programming errors
I’m writing a interpreter for my own language and I have an abstract syntax tree which has this type:
data Expression =
PInt Int
 PFloat Double
 PString String
 PChar Char
 PBool Bool
 Var String
 Unbound String String
 Unary String Expression
 Binary String Expression Expression
 Call Expression [Expression]
 Lambda Expression
 Assign String Expression Expression
 Conditional Expression Expression Expression
deriving Eq
I’m trying to write an instance of Num for my class so that I can use existing machinery for numerical operations. Here’s what I’ve written:
instance Num Expression where
PInt a + PInt b = PInt $ a + b
PInt a + PFloat b = PFloat $ a + b
PFloat a + PInt b = PFloat $ a + b
PFloat a + PFloat b = PFloat $ a + b
_ + _ = undefined
PInt a  PInt b = PInt $ a  b
PInt a  PFloat b = PFloat $ a  b
PFloat a  PInt b = PFloat $ a  b
PFloat a  PFloat b = PFloat $ a  b
_  _ = undefined
PInt a * PInt b = PInt $ a * b
PInt a * PFloat b = PFloat $ a * b
PFloat a * PInt b = PFloat $ a * b
PFloat a * PFloat b = PFloat $ a * b
_ * _ = undefined
negate (PInt a) = PInt (a)
negate (PFloat a) = PFloat (a)
negate _ = undefined
abs (PInt a) = PInt $ abs a
abs (PFloat a) = PFloat $ abs a
abs _ = undefined
signum (PInt a) = PInt $ signum a
signum (PFloat a) = PFloat $ signum a
signum _ = undefined
fromInteger i = (PInt $ fromInteger i)
This gives me errors specifically in the places where I’ve combined ints and floats.
Prelude> :load AST.hs
[1 of 1] Compiling AST ( AST.hs, interpreted )
AST.hs:38:36:
Couldn't match expected type `Double' with actual type `Int'
In the first argument of `(+)', namely `a'
In the first argument of `PFloat', namely `(a + b)'
In the expression: PFloat (a + b)
AST.hs:39:37:
Couldn't match expected type `Double' with actual type `Int'
In the second argument of `(+)', namely `b'
In the second argument of `($)', namely `a + b'
In the expression: PFloat $ a + b
AST.hs:43:33:
Couldn't match expected type `Double' with actual type `Int'
In the first argument of `()', namely `a'
In the second argument of `($)', namely `a  b'
In the expression: PFloat $ a  b
AST.hs:44:37:
Couldn't match expected type `Double' with actual type `Int'
In the second argument of `()', namely `b'
In the second argument of `($)', namely `a  b'
In the expression: PFloat $ a  b
AST.hs:48:33:
Couldn't match expected type `Double' with actual type `Int'
In the first argument of `(*)', namely `a'
In the second argument of `($)', namely `a * b'
In the expression: PFloat $ a * b
AST.hs:49:37:
Couldn't match expected type `Double' with actual type `Int'
In the second argument of `(*)', namely `b'
In the second argument of `($)', namely `a * b'
In the expression: PFloat $ a * b
Failed, modules loaded: none.
This doesn’t make sense to me, since the type of an Int + Double in Haskell is a Double, so a + b should resolve to a Double, and since the constructor for a PFloat takes a Double, no problem… why is this not the case?
Resolved: using fromIntegral
in front of the variables of type Int
fixes it.

The mathematical operators in the Num typeclass expect both of their arguments to have the same type, so you’ll have to convert the Int to a Double using
fromIntegral
before you can add them together.For example, replace this
PInt a + PFloat b = PFloat $ a + b
with this
PInt a + PFloat b = PFloat $ fromIntegral a + b
Originally posted 20131109 21:02:54.