# Haskell for Elm developers: giving names to stuff (Part 3 - Monads!)

It is finally time, I did not think I would ever write a `Monad`

tutorial, but here it is! 😅 Let us have a look at the way `Monad`

s are defined in Haskell:

```
class (Applicative m) => Monad m where
return :: a -> m a
(>>) :: m a -> m b -> m b
(>>=) :: m a -> (a -> m b) -> m b
```

The first thing we can notice again is that the typeclass definition has itself a typeclass constraint, implied by the `class Applicative m =>`

bit, just like in our previous post about Applicative Functors.

Needless to say, this means that every `Monad`

instance must satisfy the `Applicative`

instance first, and that one, in return, the `Functor`

instance. 😵💫 By the way, if you have not already, to understand this whole post and gain more intuition about `Monad`

s, you better read the previous two posts I made:

- Haskell for Elm developers: giving names to stuff (Part 1 - Functors)
- Haskell for Elm developers: giving names to stuff (Part 2 - Applicative Functors)

SPOILER ALERT ⚠️! In Elm, some examples of `Monad`

s you use every day are… 🥁🥁🥁 (*drum rolls…*) again: `List`

, `Maybe`

, `Result`

and `Task`

!!! 🤯

## The `return`

function

If you have good memory, you might be asking yourself right now: what is the difference between `pure :: a -> m a`

and `return`

?

`return :: a -> m a`

And the answer is: there is **none**.

If you want to find out the historical reasons why we ended up with two functions called different that basically do the same thing, please check this Reddit thread from 7 years go. 👴🏻 There is a modern Haskell trend to prefer `pure`

over `return`

in code (I contributed to this trend a fair bit myself), but it is totally up to you!

## The Mr. Pointy (🤣) operator (`>>`

)

I did not come up with the name, I swear, I read it in the Haskell Book™️. Some people refer to it as the *sequencing operator*, but it does not have an “official” English-language name:

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

The only thing the Mr. Pointy operator does is sequencing two actions while discarding any result value of the first action.

Let’s have another peek at the implementation of the `Monad`

typeclass in `GHC.Base`

and see what we can learn this time from it:

```
class (Applicative m) => Monad m where
-- | Sequentially compose two actions, passing any value produced
-- by the first as an argument to the second.
(>>=) :: m a -> (a -> m b) -> m b
-- | Sequentially compose two actions, discarding any value produced
-- by the first, like sequencing operators (such as the semicolon)
-- in imperative languages.
(>>) :: m a -> m b -> m b
>> k = m >>= \_ -> k
m {-# INLINE (>>) #-}
-- | Inject a value into the monadic type.
return :: a -> m a
return = pure
```

First thing we can notice is hey! Another language pragma, this time called `INLINE pragma`

, do not worry too much about it, all it is doing is performing a little optimization on the compiler level to tell GHC that it can go ahead and *inline* that function. A second thing we can notice is that Mr. Pointy (`>>`

) is defined in terms of `>>=`

:

```
(>>) :: m a -> m b -> m b
>> k = m >>= \_ -> k m
```

Because of this, we are not going to waste any time trying to find the definition of Mr. Pointy in Elm (because if you define `>>=`

for your type, you again get *for free* the definition of `>>`

), but rather cut right to the meat!

## The Monadic bind operator (`>>=`

)

I am going to try my best to give you the simplest explanation about this operator, but since I assume you know Elm, the explanation is going to be quite trivial: 😉

`(>>=) :: m a -> (a -> m b) -> m b`

By looking at the type signature of the bind operator, does it not look familiar to you, dear Elm developer? Have you ever tried to `flatMap`

a `List`

? `flatMap`

is the name chosen by JavaScript and many other languages, but Elm chose a couple of interesting ones, let us begin first with the `List`

Monad. 🙊

```
> List.concatMap
<function> : (a -> List b) -> List a -> List b
```

As you can see, `List.concatMap`

is just a flipped version of the `>>=`

operator for Elm, but what about `Maybe`

, `Result`

and `Task`

?

```
> Maybe.andThen
<function> : (a -> Maybe b) -> Maybe a -> Maybe b
```

Yes! We can say with confidence that those types satisfy the `Monad`

instance because we have `Maybe.andThen`

, `Result.andThen`

and `Task.andThen`

and all of those functions allow us to **chain computations**! 👏🏻 Hope that was not so scary after all! 👻😘

## The infamous `do`

notation

Famously, the issue with the `|> andThen`

approach, is that **elm-format** (the *de facto standard* for all Elm applications) formats everything in a rather ugly manner:

```
map5 :
a -> b -> c -> d -> e -> result)
(-> Task x a
-> Task x b
-> Task x c
-> Task x d
-> Task x e
-> Task x result
map5 func taskA taskB taskC taskD taskE =
taskA
|> andThen
a ->
(\taskB
|> andThen
b ->
(\taskC
|> andThen
c ->
(\taskD
|> andThen
d ->
(\taskE
|> andThen (\e -> succeed (func a b c d e))
)
)
) )
```

This, however, is *not an issue* that `elm-format`

is responsible for (as a matter of fact, I love `elm-format`

and think it is a **modern masterpiece** of software engineering! 😍), but it is rather a *consequence* of the language design decision *NOT* to have something like `do`

notation in Elm. For example, the above code would be really similar **without** `do`

notation in Haskell (if you use a formatter like `ormolu`

):

```
map5 ::
-> b -> c -> d -> e -> result) ->
(a Task x a ->
Task x b ->
Task x c ->
Task x d ->
Task x e ->
Task x result
=
map5 func taskA taskB taskC taskD taskE
taskA>>= \a ->
taskB>>= \b ->
taskC>>= \c ->
taskD>>= \d ->
taskE>>= \e -> pure (func a b c d e)
```

Yes, there are Haskellers that still to this very day **format their code by hand** (😅), and so they would use less indentation in the aforementioned code, but we are not gonna let humans get in the way of the machine (thank God we have formatters 😍). Nevertheless, thanks to `do`

notation, we can write it in the following manner:

```
map5 ::
-> b -> c -> d -> e -> result) ->
(a Task x a ->
Task x b ->
Task x c ->
Task x d ->
Task x e ->
Task x result
= do
map5 func taskA taskB taskC taskD taskE <- taskA
a <- taskB
b <- taskC
c <- taskD
d <- taskE
e pure $ func a b c d e
```

Doesn’t it just look beautiful!? 💜

Funnily enough,

ormoluis the closest we can get to something like`elm-format`

in Haskell (which I also love 🤩 and am using to format every code sample in this blogpost) and many Haskellers hate it for no reason at all! 🤷🏼♂️

EDIT: As pointed out by @TankorSmash on Twitter, the actual closest to

`elm-format`

would probably be`hindent-elm`

, but it might not work 100% correctly or as complete as other Haskell formatters.

## Acknowledgements

Special thanks to @forensor and other readers that have encouraged me to continue the series. Kudos to Aaron VonderHaar and to Mark Karpov for creating and maintaining `elm-format`

and `ormolu`

respectively! 🙌🏻

Thanks again to @serras for technical proofreading this post again (he single-handedly wrote an entire book exclusively about `Monad`

s after all ) and remember! **Always be nice** to each other online and have in mind that we are all in different learning paths in our lives and that we can help each other out by giving *constructive feedback*, rather than trying to destroy people’s hopes and dreams. 😅

Hope `Monad`

s finally clicked for you ✨ (if they had not already) and you learned something new! If you enjoyed this post and would like me to continue the series (*next up would probably be maybe parser combinators?*, let me know what you would like to hear next!), please share it in your social networks and

**follow me on Twitter!**🙌🏻