On Wed, 20 Feb 2002, Andre W B Furtado wrote: > hi, you sent me "blank" email (nothing besides my own message). Were you > trying to tell something? :) > > -- Andre
Heh, actually I was. I curse the day that the designers of pine put (control-X) for sending a letter next to (control-C) for killing it :) Please don't take offense to this, but do you feel unsafePerformIO is really necessary for your application? There's got to be another way... In Systematic Design of Monads [1] there is given a systematic method to wrap monads around other monads. I was going to email you an example monad which wraps around the IO monad. Granted, its a state monad wrapped around the IO monad, which may not be of much use except for organizational purposes. I've essentially stolen the design from the aforementioned paper, but since the paper appears to be for Gofer, the Haskell precursor, I decided to modernize it a bit. By the way, seems like there might be something along the lines of this in the hugs library. (If not, I'm sure I remember something about reader and writer monad wrappers) Jay Cox [1]written by John Hughes & Magnus Carlson (1996) Appologies to both since I cant give a more specific reference to the paper. John (or Magnus), you wouldn't have happened to taken the time to have updated the code from that paper, have you? If you already have, I appologize for not refering to it and using it as well :) ---- If you cut and paste the following lines I think they ought to be able to run as in a haskell.lhs source file. You proposed using some runMyMonad function. in order to combine IO actions with your code the runction returns and IO (blah). see, the IO is hidden within the new monad but IO actions are still being threaded through MyMonad. >newtype MyNewStateMonad m s a = StateMonad (s -> m (a,s)) > > >bindST (StateMonad x) f = > StateMonad (\s -> ( x s >>= \(v,s') -> let StateMonad g = f v in g s')) > >unitST v = StateMonad (\s -> return (v,s)) > > >instance Monad m => Monad( MyNewStateMonad m s) where > (>>=) = bindST > return = unitST > > >type MyMonad a = MyNewStateMonad IO Int a > >runMyMonad :: MyMonad a -> Int ->IO (a,Int) -- (a,Int) the state tuple >runMyMonad (StateMonad f) = f that's it! the remainder is mostly example code it: 1. lifts print and getLine to monadic actions under MyMonad (aka MyNewStateMonad IO Int) 2. has an example monadic action (add50toMyMonadState) which has absoultely nothing to do with the underlying IO monad. 3. lifted a sequence of IO actions to be executed under MyMonad via arbitrarysequence 4. combines all the actions under MyMonad into monad_actions so that they may be run with runMyMonad. note the line: y<- runMyMonad monad_actions 0 the 0 initializes the state of the MyMonad, (hence this is why runMyMonad is typed MyMonad a -> Int ->IO (a,Int) ) >liftIOtoMyMonad' :: (a -> IO ()) -> a -> MyMonad () >liftIOtoMyMonad' p q = > StateMonad $ \s -> do p q > return ((),s) > >liftIOtoMyMonad :: IO a -> MyMonad a >liftIOtoMyMonad p = > StateMonad $ \s -> do y <- p > return (y,s) > >liftIOtoMyMonad_ :: IO () -> MyMonad () >liftIOtoMyMonad_ m = liftIOtoMyMonad' (const m) () > > >getLineMM = liftIOtoMyMonad getLine >printMM = liftIOtoMyMonad' print >arbitrarysequence = > liftIOtoMyMonad $ > do print "What's your name?" > name <-getLine > print $ "Your name is " ++ name > > >add50toMyMonadState :: MyMonad () >add50toMyMonadState = StateMonad(\s -> return ((),50+s)) > > >monad_actions= do arbitrarysequence > printMM "What's your password" > pass <- getLineMM > printMM ("Your password is: " ++ pass) > add50toMyMonadState > return 3 > > >main = do y<- runMyMonad monad_actions 0 > print $ "State:" ++ show (snd y) ++ " Value:" ++ show (fst y) If you are reading this you should be instead copying it to some file and playing with it instead! _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell