Kiwiwache
Kiwiwache

Reputation: 21

Haskell List Syntax with :

Haskell; x,y: integers.

x : [y] : []

What happens in this case? Is [y] added to [] or is x added to [y] first? Is the result [x,[y]] or [[x,y]]?

I'm sorry for my bad English and thank you for your help.

Upvotes: 2

Views: 119

Answers (2)

Daniel Wagner
Daniel Wagner

Reputation: 152867

You can ask ghci about fixity information:

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

Ignoring the first line for a moment, the second line says infixr 5, which means that : associates to the right and has precedence 5. "Associates to the right" means the operator groups "towards the right", so e1 : e2 : e3 means e1 : (e2 : e3).

Other options include infixl (grouping "toward the left") and infix (if grouping would be needed, report an error). For example, e1 + e2 + e3 means (e1 + e2) + e3 because + is infixl:

> :i +
class Num a where
  (+) :: a -> a -> a
  ...
    -- Defined in ‘GHC.Num’
infixl 6 +

And True == True == True is a parse error because == is infix:

> :i ==
class Eq a where
  (==) :: a -> a -> Bool
  ...
    -- Defined in ‘GHC.Classes’
infix 4 ==

When there are multiple operators, the precedence is used to tell how they are grouped, but your expression involves only one operator, namely, (:), so the precedence is not needed to decide what your expression means.

Of course, you can always use explicit parentheses to disambiguate or to group operators "the other way"; e.g. (e1 : e2) : e3 is also a valid expression and means something different from e1 : (e2 : e3), and (True == True) == True is valid and evaluates to True even though True == True == True is not valid.

Here are some examples showing the difference:

> 1 : 2 : [3,4]
[1,2,3,4]
> 1 : (2 : [3,4])
[1,2,3,4]
> (1 : [2]) : [[3,4],[5]]
[[1,2],[3,4],[5]]

Or, even more to the point:

> let e1 = []; e2 = ["ab","cd"]; e3 = [["ef","gh"],["ij"]]
> e1 : e2 : e3
[[],["ab","cd"],["ef","gh"],["ij"]]
> e1 : (e2 : e3)
[[],["ab","cd"],["ef","gh"],["ij"]]
> (e1 : e2) : e3
[["","ab","cd"],["ef","gh"],["ij"]]

(Cooking up values that make both of these expressions well-typed was fun!)

Upvotes: 2

sdx23
sdx23

Reputation: 168

Look at the type

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

In words: (:) takes an a and a list of as and makes it a list of as.

Thereby, in x : [y] : [], the second part [y] : [] is a list of lists with items of the same type as y. Thereby x must be a list of items that have the same type as y. E.g.

y = 1
x = [2,3]
list = x:[y]:[]

and list is [[2,3],[1]].

Edit: Overread that x and y should be integers. That of course would not work, see the explanation and try it in ghci.

Upvotes: 1

Related Questions