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 -> STret s a)
28 data STret s a = STret (State# s) a
30 instance Functor (ST s) where
31 map f (ST m) = ST $ \ s ->
32 case (m s) of { STret new_s r ->
35 instance Monad (ST s) where
39 return x = ST $ \ s -> STret s x
40 m >> k = m >>= \ _ -> k
44 case (m s) of { STret new_s r ->
45 case (k r) of { ST k2 ->
50 fixST :: (a -> ST s a) -> ST s a
58 {-# NOINLINE unsafeInterleaveST #-}
59 unsafeInterleaveST :: ST s a -> ST s a
60 unsafeInterleaveST (ST m) = ST ( \ s ->
71 SLPJ 95/04: Why @runST@ must not have an unfolding; consider:
75 (a, s') = newArray# 100 [] s
76 (_, s'') = fill_in_array_or_something a x s'
80 If we inline @runST@, we'll get:
83 (a, s') = newArray# 100 [] realWorld#{-NB-}
84 (_, s'') = fill_in_array_or_something a x s'
88 And now the @newArray#@ binding can be floated to become a CAF, which
89 is totally and utterly wrong:
92 (a, s') = newArray# 100 [] realWorld#{-NB-} -- YIKES!!!
95 let (_, s'') = fill_in_array_or_something a x s' in
98 All calls to @f@ will share a {\em single} array! End SLPJ 95/04.
101 {-# NOINLINE runST #-}
102 runST :: (All s => ST s a) -> a
105 ST m -> case m realWorld# of
109 %*********************************************************
111 \subsection{Ghastly return types}
113 %*********************************************************
115 The @State@ type is the return type of a _ccall_ with no result. It
116 never actually exists, since it's always deconstructed straight away;
117 the desugarer ensures this.
120 data State s = S# (State# s)
121 data StateAndPtr# s elt = StateAndPtr# (State# s) elt
123 data StateAndChar# s = StateAndChar# (State# s) Char#
124 data StateAndInt# s = StateAndInt# (State# s) Int#
125 data StateAndWord# s = StateAndWord# (State# s) Word#
126 data StateAndFloat# s = StateAndFloat# (State# s) Float#
127 data StateAndDouble# s = StateAndDouble# (State# s) Double#
128 data StateAndAddr# s = StateAndAddr# (State# s) Addr#
130 data StateAndInt64# s = StateAndInt64# (State# s) Int64#
131 data StateAndWord64# s = StateAndWord64# (State# s) Word64#