
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 ) instance Monad Stack where 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: ./mymonad.hs:16:24: 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 ./mymonad.hs:19:28: 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? Thank you in advance. Michael Roth