[Haskell-cafe] State Monad

Sam G. sam.g at myrealbox.com
Thu Mar 3 22:20:55 EST 2005


Thaks a lot for your contribution, this helps me a lot, I see what I've got to do. 
However, I understand the first version (Stack.hs), but I can't get what StateM.hs is. Is 
it the same version but using state transformers, so as to be able to do IO (which I would 
need)? In fact, could you give me a simple example of how to use StackM.hs, a simple 
example that pushes some ints and add the toppest two.

Thanks a lot anyway,
Sam.

PS: In fact I'm trying to implement a simple RPN "calculator". So at first I need +, push, 
pop and view which shows the whole list. Attached is what I started to do before I get 
your mail.

Mark Carroll wrote:
> On Thu, 3 Mar 2005, Sam G. wrote:
> 
> 
>>I need a Monad to represent an internal stack. I mean I've got a lot
>>of functions which operates on lists and I would not like to pass the
>>list as an argument everytime.
>>
>>Could you help me writing this monad? To start, I just need a +
>>function which will return the sum of the 2 toppest elements of the
>>stack.
> 
> 
> I wrote one which is at,
> 
> http://www.aetion.com/src/Stack.hs
> http://www.aetion.com/src/StackM.hs
> 
> Then,
> 
> add :: Num a => Stack a ()
> 
> add =
>     do x <- pop
>        y <- pop
>        push (x + y)
> 
> or whatever.
> 
> Of course, if you use Control.Monad.State where you store the stack as a
> list then you can probably just do something like,
> 
> add = (x:y:z) <- get
>       put ((x+y):z)  
> 
> I hope that helps.
> 
> -- Mark
> 
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 
> 

-------------- next part --------------
module Main where

main = do
   putStrLn "Forth Environment\nCopyright (C) Sam G. 2005.\n"
   doLoop []

doLoop list = do
   l <- getLine
   let w = execute (pushWords (words l)) list in do
      write w
      doLoop w

write []      = return () 
write (s:ss)  = do
   putStrLn $ show (s::Int)
   write ss

pushWords []      = return []
pushWords (s:ss)  = do
   push $ read (s)
   pushWords ss

newtype State state value = State (state -> (state, value))

instance Monad (State state) where
   return v = State $ \s -> (s, v)
   State f >>= k = State $ \s -> let (s0, v0) = f s
                                     State g  = k v0
                                 in g s0

push a = State $ \s -> (a:s, a)

execute (State program) = fst . program


More information about the Haskell-Cafe mailing list