Running `:i Monad`

in ghci yields the following:

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

It also lists available instances of the *Monad* type class:

```
instance Monad m => Monad (WrappedMonad m)
-- Defined in ‘Control.Applicative’
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’
```

## Concrete type signatures

To understand similarities and differences between various instances of the *Monad* type class we will take a look at the type signatures of the `return`

, `>>=`

and `>>`

functions for `List`

, `Maybe`

and `Either`

types:

```
-- Generic
return :: a -> m a
-- List
return :: a -> [a]
-- Maybe
return :: a -> Maybe a
-- Either
return :: a -> Either l a
```

```
-- Generic
(>>=) :: m a -> (a -> m b) -> m b
-- List
(>>=) :: [a] -> (a -> [b]) -> [b]
-- Maybe
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
-- Either
(>>=) :: Either a b -> (b -> Either a c) -> Either a c
```

```
-- Generic
(>>) :: m a -> m b -> m b
-- List
(>>) :: [a] -> [b] -> [b]
-- Maybe
(>>) :: Maybe a -> Maybe b -> Maybe b
-- Either
(>>) :: Either a b -> Either a c -> Either a c
```

## Using `return`

with different types

Do you remember how we said "`pure`

lifts a value to a given type" in the previous note? `return`

is a function doing exactly the same thing for the instances of the *Monad* type class:

```
-- List
(return 2 :: [Integer]) == [2]
```

```
-- Maybe
(return 2 :: Maybe Integer) == Just 2
```

```
-- Either
(return 2 :: Either a Integer) == Right 2
```

Interactive Examples:

## Using `>>=`

with different types

`>>=`

also known as `bind`

helps us run monadic actions (values) in sequence by composing them. A value produced by the first one will be passed as an argument to the second.

After actions are defined we will use `>>=`

to sequentially execute our program:

```
addOne :: (Monad m, Num a) => a -> m a
addOne a = return (a + 1)
```

```
-- List
[ ] >>= addOne == [ ]
[1] >>= addOne == [2]
[1, 2] >>= addOne == [2, 3]
[ ] >>= addOne >>= addOne == [ ]
[1] >>= addOne >>= addOne == [3]
[1, 2] >>= addOne >>= addOne == [3, 4]
```

```
-- Maybe
Nothing >>= addOne == Nothing
Just 1 >>= addOne == Just 2
Nothing >>= addOne >>= addOne == Nothing
Just 1 >>= addOne >>= addOne == Just 3
```

```
-- Either
Left 1 >>= addOne == Left 1
Right 1 >>= addOne == Right 2
Left 1 >>= addOne >>= addOne == Left 1
Right 1 >>= addOne >>= addOne == Right 3
```

Iteractive Examples:

## Using `>>`

with different types

Similar to the bind operator `>>`

allows us to sequentially compose two actions by ignoring the value produced by the first.

```
-- List
[ ] >> [ ] == [ ]
[ ] >> [2] == [ ]
[1] >> [ ] == [ ]
[1] >> [2] == [2]
```

```
-- Maybe
Nothing >> Nothing == Nothing
Nothing >> Just 2 == Nothing
Just 1 >> Nothing == Nothing
Just 1 >> Just 2 == Just 2
```

```
-- Either
Left 1 >> Left 2 == Left 1
Left 1 >> Right 2 == Left 1
Right 1 >> Left 2 == Left 2
Right 1 >> Right 2 == Right 2
```

Interactive Examples:

I was pretty intrigued when I saw how these methods work. After reading so much about *Monads* on the internet I was pretty scared of the concept but then — after I started using them — it turned out they aren't as scary as I originally thought.

Let me know on twitter what was your experience - @maciejsmolinski.