Banging around in ghci
, I happened to notice that the expression (*) 1 [1..5]
apparently has a valid type.
:t (*) 1 [1..5]
(*) 1 [1..5] :: (Enum t, Num [t], Num t) => [t]
Apparently it is a list with several type constraints, including Num [t]
which looks impossible to me, like it should give an error.
How is this the type of the expression? Why does ghci
's :t
command not give an error here?
Let's look at how these constraints come to be to explain the type.
Numbers
In Haskell a literal number is replaced with a call to
fromInteger
(orfromRational
if it has a decimal point or an 'e' in it). This way one can write '1' and have it be float or a double or an int or whatever. The type offromInteger
isSo
1
gets desugared tofromInteger (1::Integer)
which has typeNum t => t
Ranges
In Haskell the syntax
[a..b]
is converted into the callenumFromTo a b
and the type isenumFromTo :: Enum a => a -> a -> [a]
. Putting these together we getPutting it all together
Now the type of
(*)
isNum b => b -> b -> b
so we combine these all together to get:Note that
a~b
means the typesa
andb
are the same. Combining these gives the type