Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you explain the associativity of the bind operator in this haskell expression?

Tags:

haskell

monads

Without any parentheses :

Prelude> [1,2] >>= \n -> ['a', 'b'] >>= \ch -> return (n, ch)
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

Parentheses assuming left associativity:

Prelude> ([1,2] >>= \n -> ['a', 'b']) >>= \ch -> return (n, ch)
<interactive>:22:49: Not in scope: `n'

Parentheses assuming right associativity:

Prelude> [1,2] >>= (\n -> ['a', 'b'] >>= \ch -> return (n, ch))
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

Isn't >>= left associative? When no parentheses are present, why does GHCi evaluate the expression as if >>= is right associative?

like image 295
Vamshi Surabhi Avatar asked Jul 24 '13 19:07

Vamshi Surabhi


People also ask

What do you mean by associativity of an operator?

Associativity is the left-to-right or right-to-left order for grouping operands to operators that have the same precedence. An operator's precedence is meaningful only if other operators with higher or lower precedence are present. Expressions with higher-precedence operators are evaluated first.

How does the associativity of operators works in programming?

Operators Associativity is used when two operators of same precedence appear in an expression. Associativity can be either Left to Right or Right to Left. For example: '*' and '/' have same precedence and their associativity is Left to Right, so the expression “100 / 10 * 10” is treated as “(100 / 10) * 10”.

Is Haskell right or left-associative?

Nevertheless function composition in Haskell is right associative: infixr 9 .

What does the operator do in Haskell?

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).


1 Answers

Yes, >>= is left associative. However, lambdas extend as far as possible. So the presence of the \n -> means that the only correct way to parse the expression is as

[1,2] >>= (\n -> ['a', 'b'] >>= \ch -> return (n, ch))

Note that your "left associativity" form

([1,2] >>= \n -> ['a', 'b']) >>= \ch -> return (n, ch)

isn't even scope-correct. The n in the final return is out of scope.

like image 105
kosmikus Avatar answered Oct 02 '22 18:10

kosmikus