Why does this expression have a valid type?

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?

Solution

• 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` (or `fromRational` 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 of `fromInteger` is

``````fromInteger :: Num a => a
``````

So `1` gets desugared to `fromInteger (1::Integer)` which has type `Num t => t`

Ranges

In Haskell the syntax `[a..b]` is converted into the call `enumFromTo a b` and the type is `enumFromTo :: Enum a => a -> a -> [a]`. Putting these together we get

``````[1..5] == enumFromTo (fromInteger 1) (fromInteger 5) :: (Enum a, Num a) => [a]
``````

Putting it all together

Now the type of `(*)` is `Num b => b -> b -> b` so we combine these all together to get:

``````(Num t,
Num a,
Enum a,
Num b,
t~b,
[a]~b) => b
``````

Note that `a~b` means the types `a` and `b` are the same. Combining these gives the type

``````(Num a, Enum a, Num [a]) => [a]
``````