Re: Monad composition
Andre W B Furtado wrote: Well, it's also possible to interchange data between these two monads by: unsafeIOToST :: IO a - ST s a stToIO :: ST s a - IO a Can anyone tell the possible problems related to unsafeIOToST? ^^ Probably in the same manner as with unsafePerformIO: it can break referential transparency. Indeed, unsafePerformIO m = runST (unsafeIOToST m) so they're just as unsafe as each other. John Hughes ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Monad composition
The easiest way to combine State and IO is using a monad transformer. There are some lecture notes which you might find useful at http://www.md.chalmers.se/~rjmh/Combinators/Monads/index.htm which refer to a library module http://www.md.chalmers.se/~rjmh/Combinators/MonadTransformers.hs Using this library you just build the type type StateIO s a = State s IO a which is a monad with operations readState, writeState, and lift :: IO a - StateIO s a John ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Monad composition
Well, it's also possible to interchange data between these two monads by: unsafeIOToST :: IO a - ST s a stToIO :: ST s a - IO a Can anyone tell the possible problems related to unsafeIOToST? ^^ -- Andre - Original Message - From: Tom Bevan [EMAIL PROTECTED] To: Andre W B Furtado [EMAIL PROTECTED] Cc: Haskell Cafe List [EMAIL PROTECTED] Sent: Thursday, January 24, 2002 4:13 AM Subject: Re: Monad composition Andre, I can't work out how it should be done. The way I see it, the StateIO monad should have four functions associated with it. 1/ update - a function to update the state 2/ retrieve - a function to retrieve the state from the monad These two are inherited from the standard State monad 3/ input - make a character from stndIn available to the state transformation functions 4/ output - send the state of the monad after a certain set of transformations to stndOut I've managed to write functions 1-3 but not 4. Here's my work so far.I'm not really sure if this is on the right track. Tom On Thu, 2002-01-24 at 14:32, Andre W B Furtado wrote: Hi, I have the same problem. Did anyone answered your question? Thanks, -- Andre - Original Message - From: Tom Bevan [EMAIL PROTECTED] To: Haskell Cafe List [EMAIL PROTECTED] Sent: Wednesday, January 23, 2002 4:29 AM Subject: Monad composition Hi all, I'm writing a programme which requires IO actions to be interleaved with operations on a State monad. From what I can work out, this means that the IO Monad and the StateTransformation monad need to be composed into a single highr order monad. Does anyone have any references or pointers on how this should be done? Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Monad composition
Tom Bevan wrote: Hi all, I'm writing a programme which requires IO actions to be interleaved with operations on a State monad. From what I can work out, this means that the IO Monad and the StateTransformation monad need to be composed into a single highr order monad. Does anyone have any references or pointers on how this should be done? I'd also be interested in references or pointers. While, the logic isn't hard to get right, it is easy to make do-it-yourself state monads lazier than you intended. Below is how I've done it in one project. I'd be interested in any comments from others on this code. I had two other requirements beyond what you mention. I wanted to be able to stop the computation in the middle (in case an error was detected, for example). Hence the use of the Ok_Err type. Also, I wanted to make sure that each state is evaluated before moving on to the next step of the computation; this explains the ubiquitous use of seq. You also have to make sure that the constructors for the state are strict and generally be careful that after you've computed a new state the last state is garbage. BTW the Ex in StateExTrans stands for exception, but this monad doesn't support exception handling yet, so this is a misnomer. Cheers, Theodore Norvell Dr. Theodore Norvell [EMAIL PROTECTED] Electrical and Computer Engineeringhttp://www.engr.mun.ca/~theo Engineering and Applied Science Memorial University of Newfoundland St. John's, NF, Canada, A1B 3X5 Currently visiting the Department of Computer Science and ICICS at the University of British Columbia. See my webpage for contact details. -Here is the monad- module StateExMonad( Ok_Err(..), StateExTrans(), runSET, stop, for, getState, putState, command, expression, doIO ) where data Ok_Err s a = Ok s a | Err data StateExTrans s a = SET (s - IO (Ok_Err s a)) instance Functor (StateExTrans s) where --fmap :: (a - b) - (StateExTrans s a - StateExTrans s b) fmap f x = do a - x return (f a) instance Monad (StateExTrans s) where -- return :: a - StateExTrans s a return a = SET (\ s - seq s (return (Ok s a))) -- = :: (StateExTrans s a) - (a - StateExTrans s b) - -- (StateExTrans s b) (SET st) = f = SET(\ s - seq s (do ok_err' - st s case ok_err' of (Ok s' a) - let (SET st') = f a in st' s' Err - return Err)) runSET :: StateExTrans s a - s - (IO (Ok_Err s a)) runSET (SET f) s = f s stop :: StateExTrans s a stop = SET(\s - return Err) for :: (Functor m, Monad m) = [i] - (i - m a) - m [a] for [] p = return [] for (i:rest) p = p i = (\a - fmap (a:) (for rest p)) getState = SET (\s - seq s (return (Ok s s))) putState s = SET (\_ - seq s (return (Ok s ( command :: (s - s) - StateExTrans s () command c = SET(\s - seq s (return (Ok (c s) ( expression :: (s - a) - StateExTrans s a expression e = SET(\s - seq s (return (Ok s (e s doIO :: (IO a) - StateExTrans s a doIO io' = SET(\s - seq s (io' = (\a - return (Ok s a))) ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Monad composition
Andre W B Furtado wrote: Well, it's also possible to interchange data between these two monads by: unsafeIOToST :: IO a - ST s a stToIO :: ST s a - IO a Can anyone tell the possible problems related to unsafeIOToST? ^^ Probably in the same manner as with unsafePerformIO: it can break referential transparency. changeFile fileName = unsafePerformIO (writeFile fileName Hello, world) fileContents fileName = unsafePerformIO (readFile fileName) Now, if there is a call to changeFile between two calls to fileContents with the same filename (assumed that the file didn't contain the text Hello, world) the function returns different answers in exactly syntactic identical calls. Thus, referential transparency is broken. Rijk-Jan van Haaften ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Monad composition
Andre, I can't work out how it should be done. The way I see it, the StateIO monad should have four functions associated with it. 1/ update - a function to update the state 2/ retrieve - a function to retrieve the state from the monad These two are inherited from the standard State monad 3/ input - make a character from stndIn available to the state transformation functions 4/ output - send the state of the monad after a certain set of transformations to stndOut I've managed to write functions 1-3 but not 4. Here's my work so far.I'm not really sure if this is on the right track. Tom On Thu, 2002-01-24 at 14:32, Andre W B Furtado wrote: Hi, I have the same problem. Did anyone answered your question? Thanks, -- Andre - Original Message - From: Tom Bevan [EMAIL PROTECTED] To: Haskell Cafe List [EMAIL PROTECTED] Sent: Wednesday, January 23, 2002 4:29 AM Subject: Monad composition Hi all, I'm writing a programme which requires IO actions to be interleaved with operations on a State monad. From what I can work out, this means that the IO Monad and the StateTransformation monad need to be composed into a single highr order monad. Does anyone have any references or pointers on how this should be done? Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe import Termcap import IO import Monad data State a b = State ( a - ( b , a ) ) instance Monad (State a) where return b = State ( \a - ( b , a ) ) (State st) = f = State ( \a - let ( b , a' ) = st a (State trans) = f b in trans a' ) retrieve :: ( a - b ) - State a b retrieve f = State ( \a - ( f a , a ) ) update :: ( a - a ) - State a () update f = State ( \a - ( () , f a ) ) input :: IO ( State a Char ) input = do c - getChar return ( State ( \a - ( c , a ) ) ) -- This function sends the current state to standard out -- Somehow the state upto this point is calculated and -- fed to STDOUT. Can't work out how to express this -- in Haskell output :: ( a - String ) - IO ( State a () ) run :: State a b - a - b run (State trans) init = (fst.trans) init stateAction :: State a b - IO ( State a b ) stateAction act = return ( do act ) extr = stateAction.retrieve upd = stateAction.update finalise :: State a b - a - b finalise (State trans) a = trans a