Confusion about list types in Haskell

97 Views Asked by At

As far as I understand [a] means that there can be a list that can have any number of nested lists inside.

f :: [a] -> a
f (x:xs) = x

It is possible to call f [[1,2]] or f [[[True]]]] without issues.

What I don't understand on the other hand is why does [1] :: [a] give an error in the ghci.

ghci> [1] :: [a]
<interactive>:20:2: error: [GHC-39999]
    * No instance for `Num a1' arising from the literal `1'
      Possible fix:
        add (Num a1) to the context of
          an expression type signature:
            forall a1. [a1]
    * In the expression: 1
      In the expression: [1] :: [a]
      In an equation for `it': it = [1] :: [a]

How come does it work when calling a function and it does not when defining the type of a variable?

2

There are 2 best solutions below

0
chepner On BEST ANSWER

The thing that f :: [a] -> a and [1] :: [a] both have in common is that they are both attempts to narrow the type of the thing being annotated. In the case of f, you are specifying the type of whatever gets assigned to f, while in the case of [1] you are specifying the type of [1] itself.

[a] -> a is no less specific than the inferred type of \(x:xs) -> x, so the type checker does not complain.

[a] is strictly less specific than the inferred type Number a => [a] of [1], so the type checker does complain.

9
willeM_ Van Onsem On

Well you use [1] :: [a], the problem is not the list. If you use [1] :: [a], then Haskell reasons that 1 :: a. Now if you say :: a, it means "where 1 can be of any type". Any? No, not any. It can be of all Numerical types. So you add a type constraint to it:

[1] :: Num a => [a]

so then we get:

ghci> f ([1] :: Num a => [a])
1