One aspect of Haskell that many new users find difficult to get a
handle on is *operators*. Unlike many other languages, Haskell gives a
lot of flexibility to developers to define custom operators. This can
lead to shorter, more elegant code in many cases. For example, compare
these three equivalent pieces of code:

```
v1 = mappend (mappend "hello " "there ") "world"
v2 = "hello " `mappend` "there " `mappend` "world"
v3 = "hello " ++ "there " ++ "world"
```

Unfortunately, not all operators are as self-explanatory as the `++`

operator (which, in case you’re wondering, is “list append”). This
page will attempt to cover the most common “surprising” operators. In
other words: we won’t bother covering common mathematical operators
like `+`

or `*`

, nor will we cover operators defined in less common
libraries.

It’s worth pointing out as well that for many operators, using the
Hoogle search engine can be a
great way to find out about an operator, or for that matter *any*
function. It’s
pretty easy to find `++`

that way. Go ahead, try it out now!

`$`

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

One of the most common operators, and source of initial confusion, is
the `$`

operator. All this does is *apply a function*. So, `f $ x`

is
exactly equivalent to `f x`

. If so, why would you ever use `$`

? The
primary reason is – for those who prefer the style – to avoid
parentheses. For example, you can replace:

`foo (bar (baz bin))`

with

`foo $ bar $ baz bin`

A less common but arguably more compelling use case is to capture the act of applying a function to an argument. To clarify that rather vague statement with an example:

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
double :: Int -> Int
double x = x + x
square :: Int -> Int
square x = x * x
main :: IO ()
main = print (map ($ 5) [double, square])
```

The `($ 5)`

bit means “apply the function to 5”, and then we can use
`map`

to use it with both the `double`

and `square`

functions.

`.`

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

Not much more to it than that: take two functions and compose them together.

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
double :: Int -> Int
double x = x + x
square :: Int -> Int
square x = x * x
main :: IO ()
main = (print . double . square) 5
```

Or you can combine this together with the `$`

operator to avoid those
parentheses if you’re so inclined:

`main = print . double . square $ 5`

In addition to its usage for function composition, the period is also used for hierarchical modules, e.g.:

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
import qualified Data.Monoid
main :: IO ()
main = putStrLn $ Data.Monoid.mappend "hello " "world"
```

Finally, in the `Control.Category`

module, the `Category`

typeclass
*also* uses the `.`

operator to define categorical composition. This
generalizes standard function composition, but is not as commonly
used.

`&`

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

`&`

is just like `$`

only backwards. Take our example for `$`

:

`foo $ bar $ baz bin`

This is semantically equivalent to:

`bin & baz & bar & foo`

`&`

is useful because the order in which functions are applied to their
arguments read left to right instead of the reverse (which is the case
for `$`

). This is closer to how English is read so it can improve code clarity.

In our function composition example we composed the functions
`square`

, `double`

, and `print`

and applied the resulting function to the number `5`

.

Rewriting it using `&`

gives us

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
import Data.Function
double :: Int -> Int
double x = x + x
square :: Int -> Int
square x = x * x
main :: IO ()
main = 5 & square & double & print
```

`<>`

`(<>) :: Monoid m => m -> m -> m`

The `<>`

operator is just a synonym for the
`mappend`

function. This
comes from the `Monoid`

typeclass, which represents types which have
an identity and an associative binary operation. Some examples:

- For lists,
`<>`

is the same as`++`

(append two lists) - For vectors, this logic holds as well
- For
`Set`

s, this is a union operation (all values present in either`Set`

) - For
`Map`

s, we have a “left biased union”, meaning we combine the key/value pairs from both inputs, and if both inputs share a key, the value in the left input is selected - For numbers, both addition and multiplication form a
`Monoid`

, where 0 is the additive identity (since`0 + x = x`

) and 1 is the multiplicative identity (since`1 * x = x`

). Therefore, to avoid confusion,`Data.Monoid`

defines helper newtype wrappers`Sum`

and`Product`

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
import Data.Monoid ((<>))
main :: IO ()
main = putStrLn $ "hello " <> "there " <> "world!"
```

`<$>`

```
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$) :: Functor f => a -> f b -> f a
($>) :: Functor f => f a -> b -> f b
```

The `<$>`

operator is just a synonym for the
`fmap`

function
from the `Functor`

typeclass. This function generalizes the `map`

function for lists to many other data types, such as `Maybe`

, `IO`

,
and `Map`

.

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
import Data.Monoid ((<>))
main :: IO ()
main = do
putStrLn "Enter your year of birth"
year <- read <$> getLine
let age :: Int
age = 2020 - year
putStrLn $ "Age in 2020: " <> show age
```

In addition, there are two additional operators provided which replace
a value inside a `Functor`

instead of applying a function. This can be
both more convenient in some cases, as well as for some `Functor`

s be
more efficient. In terms of definition:

```
value <$ functor = const value <$> functor
functor $> value = const value <$> functor
x <$ y = y $> x
x $> y = y <$ x
```

`<*>`

```
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(*>) :: Applicative f => f a -> f b -> f b
(<*) :: Applicative f => f a -> f b -> f a
```

Commonly seen with `<$>`

, `<*>`

is an operator that applies a wrapped
function to a wrapped value. It is part of the `Applicative`

typeclass, and is very often seen in code like the following:

`foo <$> bar <*> baz`

For cases when you’re dealing with a `Monad`

, this is equivalent to:

```
do x <- bar
y <- baz
return (foo x y)
```

Other common examples including parsers and serialization libraries. Here’s an example you might see using the aeson package:

```
data Person = Person { name :: Text, age :: Int } deriving Show
-- We expect a JSON object, so we fail at any non-Object value.
instance FromJSON Person where
parseJSON (Object v) = Person <$> v .: "name" <*> v .: "age"
parseJSON _ = empty
```

To go along with this, we have two helper operators that are less frequently used:

`*>`

ignores the value from the first argument. It can be defined as:`a1 *> a2 = (id <$ a1) <*> a2`

Or in

`do`

-notation:`a1 *> a2 = do _ <- a1 a2`

For

`Monad`

s, this is completely equivalent to`>>`

.`<*`

is the same thing in reverse: perform the first action then the second, but only take the value from the first action. Again, definitions in terms of`<*>`

and`do`

-notation:`(<*) = liftA2 const a1 <* a2 = do res <- a1 _ <- a2 return res`

```
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(=<<) :: Monad m => (a -> m b) -> m a -> m b
(>>) :: Monad m => m a -> m b -> m b
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
```

There are a few different monadic binding operators. The two most
basic are `>>=`

and `>>`

, as they can be trivially expressed in
`do`

-notation. And as previously mentioned, `>>`

is just a synonym for
`*>`

from the `Applicative`

class, so it’s even easier. `=<<`

is
just `>>=`

with the arguments reversed.

```
m1 >>= f = do
x <- m1
f x
m1 >> m2 = do
_ <- m1
m2
f =<< m1 = do
x <- m1
f x
```

In addition to these two operators, there are also composition
operators for when you have two monadic functions. `>=>`

pipes the
result from the left side to the right side, while `<=<`

pipes the
result the other way. In other words:

```
f >=> g = x -> do
y <- f x
g y
g <=< f = x -> do
y <- f x
g y
f >=> g = g <=< f
g >=> f = f <=< g
```

`<|>`

`(<|>) :: Alternative f => f a -> f a -> f a`

The `Alternative`

typeclass provides a binary operation on applicative
functors (`<|>`

), as well as some identity value (`empty`

). This is
used in the ecosystem for a number of different activities, e.g.:

- In parser libraries for defining different alternative parsing options
- In the async library to run two different
`Concurrently`

actions at once and take the first result to succeed

```
#!/usr/bin/env stack
-- stack --resolver lts-12.21 script
import Control.Applicative ((<|>))
import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (Concurrently (..))
main :: IO ()
main = do
res <- runConcurrently $
(Concurrently (threadDelay 1000000 >> return (Left "Hello"))) <|>
(Concurrently (threadDelay 2000000 >> return (Right 42)))
print res
```

If you’re aware of other common operators that cause confusion, please open an issue or a PR to extend this document!

Subscribe to our blog via email

Email subscriptions come from our Atom feed and are handled by Blogtrottr. You will only receive notifications of blog posts, and can unsubscribe any time.