Tim
Tim

Reputation: 99508

Does `('a':_)` represent a tuple or a list?

A function that decides if a list begins with the letter ’a’ can be defined as follows:

test :: [Char] -> Bool 
test ['a',_] = True  
test _ = False

or

test :: [Char] -> Bool 
test ('a':_) = True  
test _ = False

Why does the first use [], while the second uses ()?

Does the second use ('a':_) to represent a tuple or a list?

Upvotes: 4

Views: 143

Answers (3)

developer_hatch
developer_hatch

Reputation: 16214

In Haskell there are data constructors that are symbols, some examples that may confuse you:

() :: ()

that's the type unit with its constructor () and its value ()

then there is:

(,) :: a -> b -> (a,b)

(,) is the constructor for tuples, for example (1,"b") that can be (1,) “b” or (,) 1 “b”

finally your case:

(:) :: a -> [a] -> [a]

for example, 1:[] that can be [1] or (:) 1 []

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477240

Does the second use ('a':_) to represent a tuple or a list?

A list.

If a list, doesn't () represent a tuple and how can it represent a list?

No, this is the unit type [wiki]. It is not a tuple, nor a list. Sometimes, as the Wikipedia article says, it is interpreted as an 0-tuple. It is defined in GHC.Tuple as well.

Why does the first use [], while the second uses ()?

The two are not equivalent. The former one matches a list with exactly two elements where the first element is an 'a', whereas the latter matches a list with at least one element where the first element is an 'a'. But the latter can match a list with one element, three elements, etc. whereas the former can only match lists with exactly two elements.

Background

(:) is a data constructor of a list. Indeed:

Prelude> :i (:)
data [] a = ... | a : [a]   -- Defined in ‘GHC.Types’
infixr 5 :

The ('a': _) is just a nicer form of ((:) 'a' _). We here thus use one of the list data constructors.

The ['a', _] is syntactical sugar for (:) 'a' ((:) _ []), so here we match a list that starts with an 'a' and where the tail is a list with as head a value we do not care about and its tail the empty list data constructor.

Upvotes: 8

Robin Zigmond
Robin Zigmond

Reputation: 18249

Haskell's list notation is just syntactic sugar for "cons"ing elements on to the empty list (that is, using the : operator).

In other words,

[x,y,z]

is syntactic sugar for

x:(y:(z:[]))

(although this form would more normally be written as x:y:z:[] without the parentheses, since : is right-associative).

So, in the example you quote, ('a':_) represents any list whose first element is 'a', while ['a',_] is sugar for (a:(_:[])) which is a list of length exactly 2, whose first element is a.

Note that tuples are something else entirely, being denoted by a sequence of values in parentheses separated by commas.

Upvotes: 5

Related Questions