# Trivial Monad

Dan Piponi in his post about Monads started by taking a design pattern of a wrapper.

`data W a = W a deriving Show`

In this design pattern there are only two functions, one
is to wrap anything with the wrapper. Let’s call it `return'`

(otherwise
it clashes with `return`

in `Prelude`

):

```
return' :: a -> W a
return' a = W a
```

The other function is to take an unwrapping-transforming function, take a wrapped value and to convert it into another wrapped value by using the function.

```
bind :: (a -> W a) -> W a -> W b
bind f (W a) = f a
```

So while we have the option of unwrapping the value using pattern matching:

`g (W x) (W y) = ... -- do something with x and y`

We would not want to do that because in real world, this
wrapper is called `Monad`

and it quickly becomes unwieldy to pattern
match all of its subclasses. Any *unwrapping* of the values needs to be
done in the `bind`

function. Remember, we can access the unwrapped value
in the function passed to `bind`

as its first parameter.

This excellent explanation is followed by exercises.

Here are my attempts:

The first function takes an Integer and a Wrapped integer and creates
their sum. The unwrapping happens in `bind`

. This pattern is essentially
about doing something with wrapped and free value.

```
-- g x (W y) => W (x + y)
g :: Int -> W Int -> W Int
g x wy = bind (\y -> W $ x + y) wy
```

The second function takes two wrapped values and create a new one. Here the =bind=s are nested and this does not look like a very clean approach.

```
-- h (W x) (W y) => W (x + y)
h :: W Int -> W Int -> W Int
h wx wy = bind (\y -> (bind (\x -> W $ x + y) wx) wy
```

Using the above definition of `h`

, `g`

can be redefined as:

`g x wy = h (return x) wy`

We also have the option of creating Functor, Applicative, and Monad instances for W:

```
instance Functor W where
fmap f (W x) = W $ f x
instance Applicative W where
pure x = W x
W f <*> W x = W $ f x
instance Monad W where
return x = W x
W x >>= f = f x
```

So the code gets a little cleaner:

```
h' :: W Int -> W Int -> W Int
h' wx wy = wx >>= \x -> wy >>= \y -> return (x + y)
```

There’s also one method of unwrapping one layer of a doubly wrapped value:

```
join :: W (W a) -> W a
join wwa = wwa >>= id
-- join wwa = bind id wwa
```

This is a good example because the function which goes into bind has type of ```
a
-> W a
```

, and `id`

has the type `a -> a`

. I could think about the second
(commented) function only after coming up with the first one.

Therefore, `>>=`

function unwraps one `Monad`

value and transforms it to
another `Monad`

value.

`W x >>= f = f x`