2

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.

1
  • in [[x,y]] both x and y must have the same type -- in Haskell, all elements of a list must have the same type. But in [x,[y]], x must be of the same type as [y], i.e. a list, with elements of the same type as that of y. Commented Jan 28, 2017 at 23:16

2 Answers 2

2

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!)

Sign up to request clarification or add additional context in comments.

Comments

1

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.

2 Comments

If you type :i (:) in ghci you can find out, that the fixity of : is infixr. Thus, if as supposed by the OP, x and y are integers then the expression x : [y] : [] is not well typed ... If you, however evaluated (x : [y]) : [] the result would be [[x,y]].
The type cannot be used to answer OP's question, which is about fixity and parsing rules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.