X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Flib%2Fstd%2FPrelST.lhs;h=8cf8f372fba61af7cf02e4524cce88af7bf3acaf;hb=2e1d81190f5d80b1431691cc4141ca2c1719ff66;hp=a3a45a3c9390bcb025abdce405dcbcc2b021df01;hpb=449deb80dde91031b86b9cb4fb183696e0139bae;p=ghc-hetmet.git diff --git a/ghc/lib/std/PrelST.lhs b/ghc/lib/std/PrelST.lhs index a3a45a3..8cf8f37 100644 --- a/ghc/lib/std/PrelST.lhs +++ b/ghc/lib/std/PrelST.lhs @@ -1,6 +1,9 @@ +% ------------------------------------------------------------------------------ +% $Id: PrelST.lhs,v 1.21 2001/09/26 15:12:37 simonpj Exp $ % -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 +% (c) The University of Glasgow, 1992-2000 % + \section[PrelST]{The @ST@ monad} \begin{code} @@ -8,9 +11,11 @@ module PrelST where -import Monad import PrelBase -import PrelGHC +import PrelShow +import PrelNum + +default () \end{code} %********************************************************* @@ -23,7 +28,8 @@ 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} -newtype ST s a = ST (State# s -> (# State# s, a #)) +newtype ST s a = ST (STRep s a) +type STRep s a = State# s -> (# State# s, a #) instance Functor (ST s) where fmap f (ST m) = ST $ \ s -> @@ -50,13 +56,6 @@ data STret s a = STret (State# s) a liftST :: ST s a -> State# s -> STret s a liftST (ST m) = \s -> case m s of (# s', r #) -> STret s' r -fixST :: (a -> ST s a) -> ST s a -fixST k = ST $ \ s -> - let ans = liftST (k r) s - STret _ r = ans - in - case ans of STret s' x -> (# s', x #) - {-# NOINLINE unsafeInterleaveST #-} unsafeInterleaveST :: ST s a -> ST s a unsafeInterleaveST (ST m) = ST ( \ s -> @@ -104,10 +103,18 @@ f = let All calls to @f@ will share a {\em single} array! End SLPJ 95/04. \begin{code} -{-# NOINLINE runST #-} +{-# INLINE runST #-} +-- 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. runST :: (forall s. ST s a) -> a -runST st = - case st of - ST m -> case m realWorld# of - (# _, r #) -> r +runST st = runSTRep (case st of { ST st_rep -> st_rep }) + +-- I'm only letting runSTRep be inlined right at the end, in particular *after* full laziness +-- That's what the "INLINE [0]" says. +-- SLPJ Apr 99 +{-# INLINE [0] runSTRep #-} +runSTRep :: (forall s. STRep s a) -> a +runSTRep st_rep = case st_rep realWorld# of + (# _, r #) -> r \end{code}