2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrelST]{The @ST@ monad}
7 {-# OPTIONS -fno-implicit-prelude #-}
16 %*********************************************************
18 \subsection{The @ST@ monad}
20 %*********************************************************
22 The state-transformer monad proper. By default the monad is strict;
23 too many people got bitten by space leaks when it was lazy.
26 newtype ST s a = ST (State# s -> (# State# s, a #))
28 instance Functor (ST s) where
29 fmap f (ST m) = ST $ \ s ->
30 case (m s) of { (# new_s, r #) ->
33 instance Monad (ST s) where
37 return x = ST $ \ s -> (# s, x #)
38 m >> k = m >>= \ _ -> k
42 case (m s) of { (# new_s, r #) ->
43 case (k r) of { ST k2 ->
46 data STret s a = STret (State# s) a
48 -- liftST is useful when we want a lifted result from an ST computation. See
50 liftST :: ST s a -> State# s -> STret s a
51 liftST (ST m) = \s -> case m s of (# s', r #) -> STret s' r
53 fixST :: (a -> ST s a) -> ST s a
55 let ans = liftST (k r) s
58 case ans of STret s' x -> (# s', x #)
60 {-# NOINLINE unsafeInterleaveST #-}
61 unsafeInterleaveST :: ST s a -> ST s a
62 unsafeInterleaveST (ST m) = ST ( \ s ->
64 r = case m s of (# _, res #) -> res
69 instance Show (ST s a) where
70 showsPrec _ _ = showString "<<ST action>>"
71 showList = showList__ (showsPrec 0)
77 SLPJ 95/04: Why @runST@ must not have an unfolding; consider:
81 (a, s') = newArray# 100 [] s
82 (_, s'') = fill_in_array_or_something a x s'
86 If we inline @runST@, we'll get:
89 (a, s') = newArray# 100 [] realWorld#{-NB-}
90 (_, s'') = fill_in_array_or_something a x s'
94 And now the @newArray#@ binding can be floated to become a CAF, which
95 is totally and utterly wrong:
98 (a, s') = newArray# 100 [] realWorld#{-NB-} -- YIKES!!!
101 let (_, s'') = fill_in_array_or_something a x s' in
104 All calls to @f@ will share a {\em single} array! End SLPJ 95/04.
107 {-# NOINLINE runST #-}
108 runST :: (forall s. ST s a) -> a
111 ST m -> case m realWorld# of