
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. Thanks in advance, Sam.

On Thu, 2005-03-03 at 02:03 +0100, 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.
Thanks in advance, Sam.
Here's a little program for you to ponder over. Cheers, Bernie. import Control.Monad.State type Stack a = [a] push :: a -> Stack a -> Stack a push x s = x:s peek :: Stack a -> Maybe a peek (x:_) = Just x peek other = Nothing multTopTwo :: Num a => Stack a -> Stack a multTopTwo (x:y:rest) = x * y : rest multTopTwo other = other type StateStack a = State (Stack Int) a pushList :: [Int] -> StateStack () pushList [] = return () pushList (x:xs) = (modify $ push x) >> pushList xs prog :: [Int] -> StateStack (Maybe Int) prog xs = do pushList xs modify multTopTwo gets peek main = print $ evalState (prog [1..5]) []

Hello again, in fact I wrote the following state monad: -- 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) prog= do {push 100 ; push 1} execute (State program) = fst (program []) -- but I never use value, so is there a way not to write it in the monad definition? Sam. 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.
Thanks in advance, Sam.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

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

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@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
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

On Fri, 4 Mar 2005, Sam G. wrote:
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
Yes, it is. Perhaps there was a more conventional way to name it.
example that pushes some ints and add the toppest two.
Enclosed is a programme that asks for two ints from standard input, adds them along with a random number from 1 to 10, then prints the answer. I hope that it helps you.
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.
Ah, that's interesting! You've made a good start. Thinking of stacks, I've often wondered if Haskell would be a good language for implementing a PostScript interpreter. All the best, Mark
participants (5)
-
Bernard Pope
-
Mark Carroll
-
Mark Carroll
-
Sam
-
Sam G.