From 413f1d5a1537ec712423f84003cc30fbfe399f11 Mon Sep 17 00:00:00 2001 From: ross Date: Fri, 5 Sep 2003 17:36:42 +0000 Subject: [PATCH] [project @ 2003-09-05 17:36:40 by ross] minimal docs --- Control/Monad/ST.hs | 10 +++++----- Control/Monad/ST/Lazy.hs | 24 +++++++++++++++++++----- GHC/Base.lhs | 9 +++++++++ GHC/IOBase.lhs | 4 +++- GHC/ST.lhs | 12 ++++++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Control/Monad/ST.hs b/Control/Monad/ST.hs index 3ea3bb3..705787e 100644 --- a/Control/Monad/ST.hs +++ b/Control/Monad/ST.hs @@ -21,13 +21,13 @@ module Control.Monad.ST runST, -- :: (forall s. ST s a) -> a fixST, -- :: (a -> ST s a) -> ST s a - -- * Unsafe operations - unsafeInterleaveST, -- :: ST s a -> ST s a - unsafeIOToST, -- :: IO a -> ST s a - -- * Converting 'ST' to 'IO' RealWorld, -- abstract - stToIO -- :: ST RealWorld a -> IO a + stToIO, -- :: ST RealWorld a -> IO a + + -- * Unsafe operations + unsafeInterleaveST, -- :: ST s a -> ST s a + unsafeIOToST -- :: IO a -> ST s a ) where import Prelude diff --git a/Control/Monad/ST/Lazy.hs b/Control/Monad/ST/Lazy.hs index 413659e..b91e062 100644 --- a/Control/Monad/ST/Lazy.hs +++ b/Control/Monad/ST/Lazy.hs @@ -20,16 +20,16 @@ module Control.Monad.ST.Lazy ( runST, fixST, - -- * Unsafe operations - unsafeInterleaveST, - unsafeIOToST, + -- * Converting between strict and lazy 'ST' + strictToLazyST, lazyToStrictST, -- * Converting 'ST' To 'IO' RealWorld, stToIO, - -- * Converting between strict and lazy 'ST' - strictToLazyST, lazyToStrictST + -- * Unsafe operations + unsafeInterleaveST, + unsafeIOToST ) where import Prelude @@ -50,6 +50,11 @@ import Hugs.LazyST #endif #ifdef __GLASGOW_HASKELL__ +-- | The lazy state-transformer monad. +-- The first parameter is used solely to keep the states of different +-- invocations of 'runST' separate from each other and from invocations +-- of 'Control.Monad.ST.stToIO'. In the first case the type parameter +-- is not instantiated; in the second it is 'RealWorld'. newtype ST s a = ST (State s -> (a, State s)) data State s = S# (State# s) @@ -76,9 +81,15 @@ instance Monad (ST s) where k_a new_s {-# NOINLINE runST #-} +-- | Return the value computed by a state transformer computation. +-- The @forall@ is a technical device to ensure that the state used +-- by the 'ST' computation is inaccessible to the rest of the program. runST :: (forall s. ST s a) -> a runST st = case st of ST the_st -> let (r,_) = the_st (S# realWorld#) in r +-- | Allow the result of a state transformer computation to be used (lazily) +-- inside the computation. +-- Note that if @f@ is strict, @'fixST' f@ will diverge. fixST :: (a -> ST s a) -> ST s a fixST m = ST (\ s -> let @@ -123,5 +134,8 @@ unsafeInterleaveST = strictToLazyST . ST.unsafeInterleaveST . lazyToStrictST unsafeIOToST :: IO a -> ST s a unsafeIOToST = strictToLazyST . ST.unsafeIOToST +-- | A monad transformer embedding lazy state transformers in the 'IO' +-- monad. The 'RealWorld' parameter is a technical device to keep the +-- state used by such computations separate from those inside 'runST'. stToIO :: ST RealWorld a -> IO a stToIO = ST.stToIO . lazyToStrictST diff --git a/GHC/Base.lhs b/GHC/Base.lhs index f957a6d..1d786bb 100644 --- a/GHC/Base.lhs +++ b/GHC/Base.lhs @@ -991,3 +991,12 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) #-} \end{code} + +#ifdef __HADDOCK__ +\begin{code} +-- | A placeholder argument for the 'Control.Monad.ST.ST' type constructor, +-- to mark a state embedded in the 'Prelude.IO' monad by +-- 'Control.Monad.ST.stToIO'. +data RealWorld +\end{code} +#endif diff --git a/GHC/IOBase.lhs b/GHC/IOBase.lhs index be727df..b37fb1e 100644 --- a/GHC/IOBase.lhs +++ b/GHC/IOBase.lhs @@ -112,7 +112,9 @@ returnIO x = IO (\ s -> (# s, x #)) -- --------------------------------------------------------------------------- -- Coercions between IO and ST ---stToIO :: (forall s. ST s a) -> IO a +-- | A monad transformer embedding strict state transformers in the 'IO' +-- monad. The 'RealWorld' parameter is a technical device to keep the +-- state used by such computations separate from those inside 'runST'. stToIO :: ST RealWorld a -> IO a stToIO (ST m) = IO m diff --git a/GHC/ST.lhs b/GHC/ST.lhs index 65bf835..137debc 100644 --- a/GHC/ST.lhs +++ b/GHC/ST.lhs @@ -33,6 +33,11 @@ The state-transformer monad proper. By default the monad is strict; too many people got bitten by space leaks when it was lazy. \begin{code} +-- | The strict state-transformer monad. +-- The first parameter is used solely to keep the states of different +-- invocations of 'runST' separate from each other and from invocations +-- of 'Control.Monad.ST.stToIO'. In the first case the type parameter +-- is not instantiated; in the second it is 'RealWorld'. newtype ST s a = ST (STRep s a) type STRep s a = State# s -> (# State# s, a #) @@ -70,6 +75,9 @@ unsafeInterleaveST (ST m) = ST ( \ s -> (# s, r #) ) +-- | Allow the result of a state transformer computation to be used (lazily) +-- inside the computation. +-- Note that if @f@ is strict, @'fixST' f@ will diverge. fixST :: (a -> ST s a) -> ST s a fixST k = ST $ \ s -> let ans = liftST (k r) s @@ -119,6 +127,10 @@ All calls to @f@ will share a {\em single} array! End SLPJ 95/04. -- The INLINE prevents runSTRep getting inlined in *this* module -- so that it is still visible when runST is inlined in an importing -- module. Regrettably delicate. runST is behaving like a wrapper. + +-- | Return the value computed by a state transformer computation. +-- The @forall@ is a technical device to ensure that the state used +-- by the 'ST' computation is inaccessible to the rest of the program. runST :: (forall s. ST s a) -> a runST st = runSTRep (case st of { ST st_rep -> st_rep }) -- 1.7.10.4