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

 ``````1 `````` ``````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`):

 ``````1 2 `````` ``````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.

 ``````1 2 `````` ``````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:

 ``````1 `````` ``````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.

 ``````1 2 3 `````` ``````-- 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.

 ``````1 2 3 `````` ``````-- 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:

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

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

 `````` 1 2 3 4 5 6 7 8 9 10 `````` ``````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:

 ``````1 2 `````` ``````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:

 ``````1 2 3 `````` ``````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.

 ``````1 `````` ``````W x >>= f = f x ``````