Jules Bean jules at jellybean.co.uk
Mon Jan 7 09:58:46 EST 2008

```Michael Roth wrote:
> Hello list,
>
> while trying to learn the secrets of monads, I decided to write a simply
> monand for pure educational purpose. But it turned out that it isn't as
> easy as I thought... I circumnavigate quite a number of hurdles but now
> I reached a point where I'm at a loss. :-(
>
>
> The source:
>
> 	#! /usr/bin/env ghc
>
> 	data Stack a = Stack { run :: [a] -> (a, [a]) }

You want:

data Stack a b = Stack { run :: [a] -> (b, [a]) }

All monads have the property that they can represent calculations of
values of any type. Without that, they're not so useful.

So your "Stack" needs two type variables : one for the kind of thing
stacked, and one for what we're actually calculating at this instant.

The correct types for the other functions are:

> 	push :: a -> Stack a

push :: a -> Stack a ()

[you could have a -> Stack a a, if you want to echo back the pushed
value, but why bother? ]

> 	pop :: Stack a

pop :: Stack a a

> 	top :: Stack a

top :: Stack a a

With those clues I think you will be able to write >>= and return more
successfully!

There are some other interesting combinators to consider, like:

isolate :: Stack b x -> Stack a x
-- runs the computation with an empty stack, therefore
-- guaranteeing it does more pushes than pops

or

isolate :: Stack b x -> Stack a ([b],x)
-- if you want to collect the pushes.

and so on.

Jules
```