2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[STBase]{The @ST@ and @PrimIO@ monads}
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 data State a = S# (State# a)
27 newtype ST s a = ST (State s -> (a, State s))
30 = case m (S# realWorld#) of
33 instance Monad (ST s) where
37 return x = ST $ \ s@(S# _) -> (x, s)
38 m >> k = m >>= \ _ -> k
42 case (m s) of {(r, new_s) ->
43 case (k r) of { ST k2 ->
46 {-# INLINE returnST #-}
48 -- here for backward compatibility:
49 returnST :: a -> ST s a
50 thenST :: ST s a -> (a -> ST s b) -> ST s b
51 seqST :: ST s a -> ST s b -> ST s b
57 -- not sure whether to 1.3-ize these or what...
58 {-# INLINE returnStrictlyST #-}
59 {-# INLINE thenStrictlyST #-}
60 {-# INLINE seqStrictlyST #-}
62 {-# GENERATE_SPECS returnStrictlyST a #-}
63 returnStrictlyST :: a -> ST s a
65 {-# GENERATE_SPECS thenStrictlyST a b #-}
66 thenStrictlyST :: ST s a -> (a -> ST s b) -> ST s b
68 {-# GENERATE_SPECS seqStrictlyST a b #-}
69 seqStrictlyST :: ST s a -> ST s b -> ST s b
71 returnStrictlyST a = ST $ \ s@(S# _) -> (a, s)
73 thenStrictlyST (ST m) k = ST $ \ s -> -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
74 case (m s) of { (r, new_s) ->
75 case (k r) of { ST k2 ->
78 seqStrictlyST (ST m) (ST k) = ST $ \ s -> -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
79 case (m s) of { (_, new_s) ->
82 -- BUILT-IN: runST (see Builtin.hs)
84 unsafeInterleaveST :: ST s a -> ST s a -- ToDo: put in state-interface.tex
85 unsafeInterleaveST (ST m) = ST $ \ s ->
91 fixST :: (a -> ST s a) -> ST s a
99 -- more backward compatibility stuff:
100 listST :: [ST s a] -> ST s [a]
101 mapST :: (a -> ST s b) -> [a] -> ST s [b]
102 mapAndUnzipST :: (a -> ST s (b,c)) -> [a] -> ST s ([b],[c])
106 mapAndUnzipST = mapAndUnzipM
111 %*********************************************************
113 \subsection{The @PrimIO@ monad}
115 %*********************************************************
118 type PrimIO a = ST RealWorld a
120 fixPrimIO :: (a -> PrimIO a) -> PrimIO a
123 {-# GENERATE_SPECS unsafePerformPrimIO a #-}
124 unsafePerformPrimIO :: PrimIO a -> a
125 unsafeInterleavePrimIO :: PrimIO a -> PrimIO a
127 unsafePerformPrimIO = runST
128 unsafeInterleavePrimIO = unsafeInterleaveST
130 -- the following functions are now there for backward compatibility mostly:
132 {-# GENERATE_SPECS returnPrimIO a #-}
133 returnPrimIO :: a -> PrimIO a
135 {-# GENERATE_SPECS thenPrimIO b #-}
136 thenPrimIO :: PrimIO a -> (a -> PrimIO b) -> PrimIO b
138 {-# GENERATE_SPECS seqPrimIO b #-}
139 seqPrimIO :: PrimIO a -> PrimIO b -> PrimIO b
141 listPrimIO :: [PrimIO a] -> PrimIO [a]
142 mapPrimIO :: (a -> PrimIO b) -> [a] -> PrimIO [b]
143 mapAndUnzipPrimIO :: (a -> PrimIO (b,c)) -> [a] -> PrimIO ([b],[c])
145 {-# INLINE returnPrimIO #-}
146 {-# INLINE thenPrimIO #-}
147 {-# INLINE seqPrimIO #-}
149 returnPrimIO = return
152 listPrimIO = accumulate
154 mapAndUnzipPrimIO = mapAndUnzipM
158 %*********************************************************
160 \subsection{Ghastly return types}
162 %*********************************************************
165 data StateAndPtr# s elt = StateAndPtr# (State# s) elt
167 data StateAndChar# s = StateAndChar# (State# s) Char#
168 data StateAndInt# s = StateAndInt# (State# s) Int#
169 data StateAndWord# s = StateAndWord# (State# s) Word#
170 data StateAndFloat# s = StateAndFloat# (State# s) Float#
171 data StateAndDouble# s = StateAndDouble# (State# s) Double#
172 data StateAndAddr# s = StateAndAddr# (State# s) Addr#