# Random Operators: How to Make Friends and Influence Your Co-workers

If you were to ask me what language does operator overloading right, my unqualified answer would be Haskell. Unlike many languages, such as Rust or C++, operators aren’t these special things. They are just functions. Also, unlike many languages, you can define any arbitrary operator.

Now, ask me what I think is a major issue with Haskell. Do it. I dare you.

Well, if you insist…

A major issue I have with Haskell is that there are too many operators! Hundreds in base, and every library author thinks it’s ok to create hundreds more! Unfortunately, such is life; might as well get used to it.

There are two operators in particular that are quite prolific, and I think worthy of further discussion: `.`

and `$`

.

## Function Composition

Here is the type of `.`

:

`(.) :: (b -> c) -> (a -> b) -> a -> c`

`.`

is the function composition operator. Take a function `f :: a -> b`

and a function `g :: b -> c`

, you can create a function `fg :: a -> c`

:

```
fg :: a -> c
fg = g . f
```

You can chain these together too. Let `h :: c -> d`

, `i :: d -> e`

, and just for fun `j :: e -> a`

:

```
funWithCategories :: a -> a
funWithCategories = j . i . h . g . f
```

Try it with your friends! They’ll love you!

I know, it was hard for me to write too, but I’ll be darned if it doesn’t look good! Just replace the `.`

with “after”, and read it out loud:

`"j after i after h after g after f"`

Or, if you prefer to look at code:

```
funWithCategories :: a -> a
funWithCategories a = j (i (h (g (f a))))
```

… or in C:

```
a fun_with_categories(a input)
{
return j(i(h(g(f(input)))));
}
```

## Function Application

Now, let’s talk about `$`

the function application operator. Here is the type of `$`

:

`($) :: (a -> b) -> a -> b`

Basically it applied its right hand side argument to the left hand side function. Thus `show 1`

is the same thing as `show $ 1`

. However, there’s a twist. Function application in Haskell is the highest precedence thing that can happen. This means that we often have to use a lot of parenthesis to make our code compile. Say I wanted to convert the output of `2 + 2`

. This won’t work:

```
Prelude> show 2 + 2
<interactive>:25:8:
No instance for (Num String) arising from a use of ‘+’
In the expression: show 2 + 2
In an equation for ‘it’: it = show 2 + 2
```

What actuall happened was:

`(show 2) + 2`

…and that’s just silly. To make this code compile, we have to add parenthesis:

```
Prelude> show (2 + 2)
"4"
```

which is kind of annoying. However, we can use `$`

to eliminate these parenthesis!

```
Prelude> show $ 2 + 2
"4"
```

The function application operator has a precedence of 0, so the addition happens first! It has a right fixity so you can chain it!

```
funWithOperators :: a -> a
funWithOperators a = j $ i $ h $ g $ f a
```

## Hey, I’ve Seen That Function Before!

If this looks familiar to you, then you’ve been paying attention!

```
($) :: (a -> b) -> a -> b
(.) :: (b -> c) -> (a -> b) -> a -> c
```

If you chop off the first argument of `.`

and squint, they kind of look the same. Logically, they can often be used interchangeably, however you will end up using some parenthesis with `.`

.

My advice:

Use `$`

if you’re trying to produce a value for use *right now*. If you find yourself doing something like this:

`show (show ( show( show "catcatcatcat")))`

… then change it to this and save yourself the hassle of counting parenthesis:

`show $ show $ show $ show "catcatcatcat"`

Use `.`

when you’re trying to make a function. If you find yourself doing something like this:

```
showWith :: (Show a) => (a -> String) -> a -> String
showWith = -- stuff
shower :: (Show a) => a -> String
shower a = show $ show $ show $ show a
showWith shower "catcatcatcat"
```

… then you can avoid defining shower like so:

`showWith (show . show . show . show) "catcatcatcat"`

## Trackbacks / Pingbacks