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(orfromRationalif 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 offromIntegerisSo
1gets desugared tofromInteger (1::Integer)which has typeNum t => tRanges
In Haskell the syntax
[a..b]is converted into the callenumFromTo a band the type isenumFromTo :: Enum a => a -> a -> [a]. Putting these together we getPutting it all together
Now the type of
(*)isNum b => b -> b -> bso we combine these all together to get:Note that
a~bmeans the typesaandbare the same. Combining these gives the type