# # Fixity declarations

## # Associativity

`infixl`

vs `infixr`

vs `infix`

describe on which sides the parens will be grouped. For example, consider the following fixity declarations (in base)

```
infixl 6 -
infixr 5 :
infix 4 ==
```

The `infixl`

tells us that `-`

has left associativity, which means that `1 - 2 - 3 - 4`

gets parsed as

```
((1 - 2) - 3) - 4
```

The `infixr`

tells us that `:`

has right associativity, which means that `1 : 2 : 3 : []`

gets parsed as

```
1 : (2 : (3 : []))
```

The `infix`

tells us that `==`

cannot be used without us including parenthesis, which means that `True == False == True`

is a syntax error. On the other hand, `True == (False == True)`

or `(True == False) == True`

are fine.

Operators without an explicit fixity declaration are `infixl 9`

.

## # Binding precedence

The number that follows the associativity information describes in what order the operators are applied. It must always be between `0`

and `9`

inclusive. This is commonly referred to as how tightly the operator binds. For example, consider the following fixity declarations (in base)

```
infixl 6 +
infixl 7 *
```

Since `*`

has a higher binding precedence than `+`

we read `1 * 2 + 3`

as

```
(1 * 2) + 3
```

In short, the higher the number, the closer the operator will "pull" the parens on either side of it.

### # Remarks

## # Example declarations

`infixr 5 ++`

`infixl 4 <*>, <*, *>, <**>`

`infixl 8`

shift`,`

rotate`,`

shiftL`,`

shiftR`,`

rotateL`,`

rotateR```infix 4 ==, /=, <, <=, >=, >`

`infix ??`

#### # Syntax

- infix [integer] ops
- infixl [integer] ops
- infixr [integer] ops

#### # Parameters

Declaration component | Meaning |
---|---|

`infixr` | the operator is right-associative |

`infixl` | the operator is left-associative |

`infix` | the operator is non-associative |

optional digit | binding precedence of the operator (range 0...9, default 9) |

`op1, ... , opn` | operators |

#### # Remarks

To parse expressions involving operators and functions, Haskell uses fixity declarations to figure out where parenthesis go. In order, it

- wraps function applications in parens
- uses binding precendence to wrap groups of terms all seperated by operators of the same precedence
- uses the associativity of those operators to figure out how to add parens to these groups

Notice that we assume here that the operators in any given group from step 2 must all have the same associativity. In fact, Haskell will reject any program where this condition is not met.

As an example of the above algorithm, we can step though the process of adding parenthesis to `1 + negate 5 * 2 - 3 * 4 ^ 2 ^ 1`

.

```
infixl 6 +
infixl 6 -
infixl 7 *
infixr 8 ^
```

`1 + (negate 5) * 2 - 3 * 4 ^ 2 ^ 1`

`1 + ((negate 5) * 2) - (3 * (4 ^ 2 ^ 1))`

`(1 + ((negate 5) * 2)) - (3 * (4 ^ (2 ^ 1)))`

More details in section 4.4.2 of the Haskell 98 report (opens new window).