# Monad

- 25 minutes

Welcome back to the final lesson in the *Beginner Crash Course*!

We’ll pick up where we left off with the code that we wrote in the last lesson on Functor and also the `rejectNonalphabetic`

function that we wrote a few lessons ago when we discussed folds. (We have replaced `myAll`

with the regular `Prelude`

function `all`

.)

```
import Data.Char
database :: [(Integer, String)]
database = [(1, "Julie"),
(2, "Chris"),
(3, "Alonzo"),
(4, "Melman")]
greetUser :: Integer -> Maybe String
greetUser record =
fmap ("Hello, " ++) (lookup record database)
rejectNonalphabetic :: String -> Maybe String
rejectNonalphabetic string =
case (all isAlpha string) of
False -> Nothing
True -> Just string
```

We wrote this `rejectNonalphabetic`

function enforce a rule on some input – let’s say it’s username that someone entered while trying to sign up for our wonderful website – to ensure that the string contains only letters. If our input contains any other kind of character we don’t like, we’ll turn the whole thing into `Nothing`

.

## More validation functions

Let’s say we have another one that removes spaces, without rejecting the input. We’ll assume that if the user typed in any spaces, then it was just a mistake, so we can pull out the spaces. But we do want to reject the input if there’s nothing left once the spaces are gone. This function will have the same type: `String`

to `Maybe String`

.

```
removeSpaces :: String -> Maybe String
removeSpaces string =
case (filter (\x -> not (x == ' ')) string) of
"" -> Nothing
result -> Just result
```

We start with a filter to remove spaces, and put that into a `case`

expression to further inspect the results after the filtering. If we’re left with the empty string, we’ll return a `Nothing`

; if we’re left with any other `result`

, then we’ll return `Just`

that `result`

.

Finally, we could add a check to make sure usernames aren’t unreasonably long.

```
validateLength :: String -> Maybe String
validateLength string =
case (length string > 25) of
True -> Nothing
False -> Just string
```

If the number of characters in the string is more than 25, we’ll call that too long. Otherwise, we’ll return just the string.

## Composition

So now we have three rules that we want our inputs to pass. We’re going to reject anything nonalphabetic, remove spaces, and check the length. What we need to do is compose these three rules so that they are all applied the input string, and a failure at any of the three steps gives us a failure of the overall process.

The order here is going to matter, for a few reasons.

- Spaces are not alphabetic characters, so we want to remove those before we reject nonalphabetic characters. If the input has some combination of spaces and alphabetic characters, we want to consider that valid input.
- Space removal might bring a long string under the 25-character limit, so we’ll also want it to come before the length check.

We could write one long function that nests all the various case expressions that we’re using:

```
makeUsername :: String -> Maybe String
makeUsername string =
case removeSpaces string of
Nothing -> Nothing
Just xs ->
case (rejectNonalphabetic xs) of
Nothing -> Nothing
Just xs' ->
...
```

This is valid Haskell, but these can get quite long and hard to read and think about, especially if we need to add more steps later (or remove some). And you sometimes have to rename arguments to avoid shadowing (that’s what `xs`

and `xs'`

are: new names).

We might initially be tempted to try just composing them in some way, perhaps:

```
makeUsername :: String -> Maybe String
makeUsername string =
validateLength (rejectNonalphabetic (removeSpaces string))
```

Unfortunately, the compiler will reject this and chastise you with a big intimidating type error. Each one of these functions returns `Maybe String`

. We want to be able to pass the `String`

output as the input to the next rule, as if the `Maybe`

weren’t there.

You may remember that we did something like this earlier using the `<-`

arrow with `do`

syntax before when we wrote our first `main`

action.

When we had an `IO String`

action from `getLine`

and what we wanted was the `String`

that the action produces, this `<-`

form allowed us to sort of “get the `String`

out of the `IO String`

”. But Haskell also has an operator that does this. It is so important and beloved that it is, in fact, part of the Haskell logo.

## In a bind

This is called the *bind* operator: `(>>=`

).There is also the Kleisli composition operator (`>=>`

) that you could use equally well for this example, but we will focus on `(>>=)`

.

We will discuss the type in a moment, but we’ll start by showing how it’s used. Here is the concise way to write `makeUsername`

instead of the big nested `case`

expression above:

```
makeUsername :: String -> Maybe String
makeUsername string =
removeSpaces string >>= rejectNonalphabetic >>= validateLength
```

The result from `removeSpaces`

is going to effect the whole rest of the computation, just like the `case`

expressions. The first time we hit a `Nothing`

, then the whole evaluation is going to stop. But if it’s a `Just`

, then the string will get passed as the input to the next function. In this way, we can keep passing `String`

s out of `Maybe String`

s into the next function – almost like magic. But it’s not magic.

The type signature of bind looks like this:

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

In the context of our `makeUsername`

function, `m`

is `Maybe`

. The first argument `(Maybe a)`

is the output from applying a validation rule, and the second argument `(a -> Maybe b)`

is the next validation rule to feed the result into.

Let’s look at the type of this operator in GHCi to make sure we got it exactly right. To query the type of an infix operator, you need to write it with parentheses around it:

```
λ> :type (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
```

In the previous lesson we saw the type of `fmap`

written using a type variable `f`

, where the letter F was chosen as an abbreviation for Functor. Here the letter `m`

was chosen because this type contructor must be a Monad (`Maybe`

is one such type constructor).

We are going to use a language extension called type applicationsWe use the `:set`

GHCi command here to enable this language extension. Type applications is a very nice feature, and we have it enabled by default in our GHCi configuration because we use it in the REPL often. that allows us to see the result of applying a function to a type. First we’ll query for the type of `(>>=)`

applied to `Maybe`

:

```
λ> :set -XTypeApplications
λ> :type (>>=) @Maybe
(>>=) @Maybe :: Maybe a -> (a -> Maybe b) -> Maybe b
```

The type parameter `m`

is allowed to turn into `Maybe`

because `Maybe`

belongs to the `Monad`

class. You can check to see if some of your favorite type constructors are also monads. Recall that list is a Functor; does it also belong to the class of Monad? Try applying `(>>=)`

to `[]`

to find out:

```
λ> :type (>>=) @[]
(>>=) @[] :: [a] -> (a -> [b]) -> [b]
```

It is!

Let’s ask GHCi what it knows about `Monad`

.

```
λ> :info Monad
class Applicative m => Monad (m :: * -> *) where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
{-# MINIMAL (>>=) #-}
-- Defined in ‘GHC.Base’
instance Monad (Either e) -- Defined in ‘Data.Either’
instance Monad [] -- Defined in ‘GHC.Base’
instance Monad Maybe -- Defined in ‘GHC.Base’
instance Monad IO -- Defined in ‘GHC.Base’
instance Monad ((->) r) -- Defined in ‘GHC.Base’ instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’
```

This class has the constraint `Applicative m =>`

`Applicative`

is a lovely class which unfortunately did not fit into the time alotted for this course. We treat it extensively in Functortown. – a constraint on a class is called a *superclass*. This means that every `m`

that belongs `Monad`

class must also belong to the `Applicative`

class.

Like `Functor`

, the kind signature is `(* -> *)`

– So, `Monad`

and `Functor`

are classes for the same *kindedness* of things: type constructors that have exactly one type parameter.

The type signature for bind `(>>=)`

tells us that if `m`

is a monad, then there is a function `m a -> (a -> m b) -> m b`

. So what does it mean for a type `m`

to *be* a monad? We’ve been talking a lot about what typeclasses mean and their relationship with type; a class is something that many types have in common. There are many types that support this bind operation; if a type does, then it belongs to the `Monad`

class.

You’ll sometimes hear us speak of something as being “*in* a monad”. In this program, we have a lot of `Maybe String`

values, so we have `String`

s in the `Maybe`

monad.

## Lookup, then validate

Let’s see, as a final move, if we can bring together our `greetUser`

function and our `database`

with our validation function that we have now written. Let’s say when we greet a user that has logged into our website, we will validate the name before we greet them, and we won’t greet them if they have broken our rules.

`(lookup record database)`

will find us, maybe, a name from the database. So what we want to do is take that `String`

(if it found one) and pass it as the argument for `makeUsername`

. How do we do that? We bind them.

```
greetUser :: Integer -> Maybe String
greetUser record =
fmap ("Hello, " ++) (lookup record database >>= makeUsername)
```

If you have a series of computations that should be performed sequentially, such that each new one depends on the successful result of the one before it, then you may want to use `>>=`

to chain them together. You can do this if they are wrapped up in a `Monad`

, like `Maybe`

.

Let’s modify the database so that it includes an invalid name.

```
database :: [(Integer, String)]
database = [(1, "J00li3"),
(2, "Chris"),
(3, "Alonzo"),
(4, "Melman")]
```

Now we can `:reload`

and try it out.

```
λ> :reload
λ> greetUser 1
Nothing
```

User number 1 exists, but her name does not pass the `rejectNonalphabetic`

rule. But user number 3 is a very good dog:

```
λ> greetUser 3
Just "Hello, Alonzo"
```

If there is no record, what will happen?

```
λ> greetUser 5
Nothing
```

Nothing! `Nothing`

will happen.

If we care to distinguish between the multiple causes of failureTo explore this path, continue on to The Validation Course, which addresses the `Either`

and `Validation`

types. – where the record does not exist, versus when it exists but is invalid – then we would want to use a more exciting type than `Maybe`

.

## How do you do

Since you generally want side effects to be sequenced, and we use the `IO`

type constructor for side-effecting code, `IO`

– the obligatory type constructor for the `main`

action – is a canonical `Monad`

. When we first wrote out the `main`

for our interactive palindrome code some time ago, it looked like this:

```
main :: IO ()
main =
do
word <- getLine
print (isPalindrome word)
isPalindrome :: String -> Bool
isPalindrome string = string == reverse string
```

Just about any time you see `do`

,(Sometimes there’s an `Applicative`

context, using the `ApplicativeDo`

language extension.) what’s going on there is that there’s a monadic context. In the case of `main`

, that context is `IO`

. What’s really going on here just under the surface is that the compiler is inserting a bind between each line within the `do`

block.

If we prefer to write `main`

using `>>=`

instead of in the `do`

form, it could look like this:

One reason we often hesitate to include `Monad`

in beginner content is that there are a lot of people on the internet who do not really appear to be altogether interested in learning Haskell but *really* want to know what a monad is, and it feels like monads have taken on a sort of outsized mythical status. But the `Monad`

class is a fairly small thing, once you understand Haskell’s larger system of types, classes, and functions that it fits into.

This is a very common programming task, chaining together a series of functions in some particular way; `Monad`

and the `>>=`

operator is a way of simplifying that. In some ways it may not seem like a simplification when it is new to you, but by giving us certain intuitions about how the pattern should behave, and by being highly composable, the monad idea does remove some complexity – as a good abstraction should.

Everything we do in Haskell, even I/O, can be done without the `Monad`

generalization, but not quite as easily or consistently. Many Haskell learners, ourselves included, have built this concept up in our minds as a huge thing, and it felt a bit anticlimactic to find out that a shared pattern of this `(>>=)`

function is all it is. Instead of nesting `case`

expressions or something like that, we chain stuff together with an infix operator.

## Where to go from here

That concludes this beginner course. There is, of course, much more to be said about Haskell! Our goal here has been to stick with a few key ideas and repeat some important idiomatic syntax, to give you a stepping stone to go on to learn however much Haskell in the future you would like to learn.

If you’ve enjoyed this introduction, please consider looking at our other courses. Here are a few recommended followups to *The Beginner Crash Course*:

- The Validation Course works through a single example in depth. It contains a little review of what you have learned in this course and covers
`Either`

,`Validation`

, and`Applicative`

(and more!). - The Haskell Phrasebook is a collection of short annotated Haskell programs. This is a good place to look if you are eager to get some quick exposure to what software written in Haskell can look like.
- Intro to extensions will set you down the path of learning everything there is to know about all the features of the Haskell language.