I'm a Haskell newbie currently learning about expressions and types. I recently learned that it's possible to use class constraints when specifying types in Haskell. To experiment with this, I tried the following code in GHCi:
ghci> a = 3 :: Num a => a
ghci> :t a
a :: Num a => a
ghci> :i Num
type Num :: * -> Constraint
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
{-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
-- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Num Int -- Defined in ‘GHC.Num’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Word -- Defined in ‘GHC.Num’
ghci> :t (==)
(==) :: Eq a => a -> a -> Bool
ghci> a == 5
False
I don’t understand why the expression a == 5
works without any errors. The variable a has the type Num a => a
, and since the Num
class does not define the (==)
function, I expected a type error.
Could someone explain why this works?
ghci
will ad-hoc try to assign a type to a
. If you write:
a = 3 :: Num a => a
You actually have written something like:
a = fromInteger 3
which thus can be specialized to an Integer
, Double
, etc.
Now in the context of a == 5
, it thus requires a
to be (Num a, Eq a) => a
.
It will perform type defaulting and in thus case use Integer
. It thus checks for:
fromInteger 3 == fromInteger 5
and specializes the two to Integer
and then runs the (==)
function on these.
Types in Haskell are a bit "opposite" to what those are in for example Java. If in Java you write:
MyInterface foo;
It means that we only know foo
is an instance of MyInterface
.
Whereas in Haskell if we write:
x :: Num a => a
It means that x
is of a type a
for which Num a
holds. If we later use x
in another context, it can require extra type constraints.
If we thus write a function:
eq5 :: (Num a, Eq a) => a -> Bool
eq5 x = x == 5
Haskell thus promises that it will work for all types a
for which Num a
and Eq a
are satisfied.