Michael Roth mroth at nessie.de
Mon Jan 7 09:33:51 EST 2008

```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]) }

push :: a -> Stack a
push x = Stack f where f xs = ( x, x:xs )

pop :: Stack a
pop = Stack f where f (x:xs) = ( x, xs )

top :: Stack a
top = Stack f where f (x:xs) = ( x, x:xs )

return x = Stack f where f xs = ( x, xs )
(>>=) stack g = Stack f where
f s0 = (x2, s2) where
(x1, s1) = run stack s0
(x2, s2) = run (g x1) s1

The errors:

Couldn't match expected type `b' (a rigid variable)
against inferred type `a' (a rigid variable)
`b' is bound by the type signature for `>>=' at <no location info>
`a' is bound by the type signature for `>>=' at <no location info>
Expected type: [b] -> (b, [b])
Inferred type: [a] -> (b, [b])
In the first argument of `Stack', namely `f'
In the expression: Stack f

Couldn't match expected type `b' (a rigid variable)
against inferred type `a' (a rigid variable)
`b' is bound by the type signature for `>>=' at <no location info>
`a' is bound by the type signature for `>>=' at <no location info>
Expected type: [b]
Inferred type: [a]
In the second argument of `run', namely `s1'
In the expression: run (g x1) s1

I think the problem is that my operator (>>=) is of type:

Stack a -> (a -> Stack a) -> Stack a

but should be:

Stack a -> (a -> Stack b) -> Stack b

But, I have simply no clue how to fix that. :-(
Can anybody give my a hint?