[project @ 1999-12-20 10:34:27 by simonpj]
[ghc-hetmet.git] / ghc / lib / std / PrelST.lhs
index 6addc5c..b41c079 100644 (file)
@@ -9,8 +9,12 @@
 module PrelST where
 
 import Monad
+import PrelShow
 import PrelBase
 import PrelGHC
+import PrelNum ()      -- So that we get the .hi file for system imports
+
+default ()
 \end{code}
 
 %*********************************************************
@@ -23,7 +27,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 +55,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,24 +102,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
-\end{code}
-
-%*********************************************************
-%*                                                     *
-\subsection{Ghastly return types}
-%*                                                     *
-%*********************************************************
-
-The @State@ type is the return type of a _ccall_ with no result.  It
-never actually exists, since it's always deconstructed straight away;
-the desugarer ensures this.
-
-\begin{code}
-data State          s     = S#              (State# s)
+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 100" says.
+--             SLPJ Apr 99
+{-# INLINE 100 runSTRep #-}
+runSTRep :: (forall s. STRep s a) -> a
+runSTRep st_rep = case st_rep realWorld# of
+                       (# _, r #) -> r
 \end{code}