TMOTTM
TMOTTM

Reputation: 3391

Haskell: Why does (x:xs) match the list with only one element?

Given this definition of a function f:

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

I would assume that a call such as

f [1]

would not match, because the pattern (x:xs) only matches, if there are more elements xs after the x in the list, which is not the case for the list [1]. Or is it?

Upvotes: 2

Views: 2687

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477318

If you write [x], a list with one element, this is short for (x : []), or even more verbose (:) x []. So it is a "cons" ((:)) with x as element, and the empty list as tail.

So your function f (x:xs) will indeed match a list with one (or more) elements. For a list with one element, x will be the element, and xs an empty list.

would not match, because the pattern (x:xs) only matches, if there are more elements xs after the x in the list, which is not the case for the list [1].

No the (x:xs) matches with every non-empty list, with x the first element of the list, and xs a (possibly empty) list of remaining elements.

If you want to match only lists with for example two or more elements. You can match this with:

-- two or more elements
f (x1 : x2 : xs) = …

Here x1 and x2 will match the first and second item of the list respectively, and xs is a list that contains the remaining elements.

EDIT: to answer your comments:

I wonder why my function definition does even compile in the first place, because the function type is [Int] -> [Int], so if I give it the empty list, then that is not [Int] as a result, is it?

The empty list [] is one of the data constructors of the [a] type, so that means that [] has type [] :: [a]. It can match the type variable a with Int, and thus [] can have type [] :: [Int].

Second then, how to I match a list with exactly two elements? [a, b]?

You can match such list with:

f (a : b : []) = …

or you can match it with:

f [a, b] = …

The two are equivalent. [a, b] is syntactical sugar: it is replaced by the compiler to (a : b : []), but for humans, it is of course more convenient to work with [a, b].

Upvotes: 10

Related Questions