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

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