Hi Diego,

>>>>> "Diego" == Diego Dainese <[EMAIL PROTECTED]> writes:

    Diego> - In Haskell is there some way to combine IO and ST? 

there is a so-called IOS-Monad combining IO and State, appended below.
Thanks to John O'Donnell who told me about it and gave it to me a few weeks ago.

Cheers
Christoph
------------------------------------------------------------------------------
                     IOS: Input/Output with state

> module IOS where

> newtype IOS s a = IOS (s -> IO (a, s))

> unIOS :: IOS s a -> (s -> IO (a, s))
> unIOS (IOS m) = m

> liftIOS :: IO a -> IOS s a
> liftIOS m = IOS (\s -> m >>= \a -> return (a,s))

> runIOS :: IOS s a -> s -> IO (a, s)
> getIOS :: IOS s s
> setIOS :: s -> IOS s ()
> modIOS :: (s -> s) -> IOS s s

> runIOS        = unIOS 
> modIOS f      = IOS (\s -> return (s, f s))
> setIOS s'     = IOS (\s -> return ((),s'))
> getIOS        = IOS (\s -> return (s,s))

> thenIOS m k= IOS (\s -> unIOS m s >>= \(a,s') -> unIOS (k a) s')
> then_IOS m k= IOS (\s -> unIOS m s >>= \(_,s') -> unIOS k s')
> retIOS a = IOS (\s -> return (a,s))

> instance Monad (IOS s) where
>   (>>=)  = thenIOS
>   (>>)   = then_IOS
>   return = retIOS

---------------------------------------------------------------------------
-- Basic operations for data parallel monad

> rundp :: IOS s a -> s -> IO ()
> rundp prog initst =
>   do runIOS prog initst
>      return ()

> dp_putStr :: String -> IOS s ()
> dp_putStr xs = liftIOS (putStr xs)

> dp_getChar :: IOS s Char
> dp_getChar = liftIOS getChar

> dp_showState :: Show s => String -> IOS s ()
> dp_showState cs =
>   do dp_putStr cs
>      x <- getIOS
>      dp_putStr (show x)
>      dp_putStr "\n"
>      return ()

> dp_showStatenew :: (s -> IO ()) -> IOS s ()
> dp_showStatenew f =
>   do x <- getIOS
>      liftIOS (f x)
>      dp_putStr "\n"
>      return ()

> repeatLoop f =
>   do q <- f
>      if q then repeatLoop f
>           else return ()

---------------------------------------------------------------------------
-- Data parallel monadic operations with list state

> dpl_map :: (a->a) -> IOS [a] [a]
> dpl_map f = modIOS (map f)

> dpl_foldl :: (a->b) -> (b->b->b) -> b -> IOS [a] b
> dpl_foldl f g a =
>   do xs <- getIOS
>      return (foldl g a (map f xs))

---------------------------------------------------------------------------
-- Examples of monadic data parallel programs

-- Basic I/O with dp operations in the IOS monad

> dp_echoChar :: IOS [Int] ()
> dp_echoChar =
>   do dp_putStr "This is dp_echoChar, type in a character for me!\n"
>      c <- dp_getChar
>      dp_putStr ("\nyou typed in the character ---" ++ [c] ++ "---\n")
>      dp_showState "this is the initial state:\n  "
>      dp_putStr "bye\n"
>      return ()

> run_echoChar = rundp dp_echoChar [1..10]

Monadic data parallel maps, folds and scans with list state

> dp_alg :: IOS [Int] ()
> dp_alg =
>   do dp_putStr "\nThis is dp_alg\n"
>      dp_showState "initial state:\n  "
>      dpl_map (*10)
>      dp_showState "after mapping (*10):\n  "
>      x <- dpl_foldl id (+) 0
>      dp_putStr ("dplfold id (+) ==> " ++ show x ++ "\n")
>      dpl_map (+x)
>      dp_showState "after mapping (+x):\n  "
>      dp_putStr "bye\n\n"
>      return ()

> run_dp_alg = rundp dp_alg [1..10]

---------------------------------------------------------------------------
-- The pure Data Parallel monad (without I/O)

> data DP s a = DP (s -> (a,s))

 instance Monad (DP s) where
   (f >>= g) =
     DP (\s -> case unwrapDP f s of
                 (a,s') -> unwrapDP (g a) s')
   return a = DP (\s -> (a,s))

 unwrapDP :: DP s a -> (s ->(a,s))
 unwrapDP (DP f) = f
===========================================================================
END of mail

Reply via email to