# A curious associativity of the <$> operator

Published on

The `<$>`

operator in Haskell is an infix synonym for `fmap`

and has the type

For example:

Like all other operators, `<$>`

has a *fixity*, which can be `infixl`

, `infixr`

, or `infix`

. The fixity defines how an expression like

is parsed.

If `<$>`

were defined as `infix`

, then the above expression wouldn’t parse at all, giving an error like

```
Precedence parsing error
cannot mix ‘<$>’ [infix 4] and ‘<$>’ [infix 4] in the same infix expression
```

If `<$>`

instead were defined as `infixr`

, then the above expression would parse as

meaning first apply `negate`

to 5 inside `Just`

, and then go inside `Just`

once more and apply `abs`

.

However, `<$>`

is defined as `infixl`

, so that the applicative chains like

would parse correctly. This means that

is parsed as

which is probably not what you meant. Or is it?

It turns out that if you paste that expression (either parenthesized or not) into ghci, you’ll get back `Just 5`

in all cases.

This happens because of the following instance defined in the base library:

(Note that `(->) r`

is essentially the Reader monad, so it’s not surprising that it’s a functor.)

So the expression

does make sense and is equivalent to

The operators `*`

for which `a * (b * c) = (a * b) * c`

are called *associative*. Usually associative operators have the type `a -> a -> a`

(either polymorphic of for a specific `a`

), so that both ways to put parentheses typecheck.

The `<$>`

operator is curious because it doesn’t have such a type and yet is associative:

```
f <$> (g <$> h) =
{- the definition of <$> -}
fmap f (fmap g h) =
{- the definition of (.) -}
(fmap f . fmap g) h =
{- the functor law -}
fmap (f . g) h =
{- the definition of <$> -}
(f . g) <$> h =
{- the Functor instance for (->) r -}
{- g has to be a function for the top expression to typecheck -}
(f <$> g) <$> h
```