2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[STBase]{The @ST@ and @PrimIO@ monads}
15 %*********************************************************
17 \subsection{The @ST@ monad}
19 %*********************************************************
21 The state-transformer monad proper. By default the monad is strict;
22 too many people got bitten by space leaks when it was lazy.
25 data State a = S# (State# a)
26 newtype ST s a = ST (State s -> (a, State s))
29 = case m (S# realWorld#) of
32 instance Monad (ST s) where
36 return x = ST $ \ s@(S# _) -> (x, s)
37 m >> k = m >>= \ _ -> k
41 case (m s) of {(r, new_s) ->
42 case (k r) of { ST k2 ->
45 {-# INLINE returnST #-}
47 -- here for backward compatibility:
48 returnST :: a -> ST s a
49 thenST :: ST s a -> (a -> ST s b) -> ST s b
50 seqST :: ST s a -> ST s b -> ST s b
56 -- not sure whether to 1.3-ize these or what...
57 {-# INLINE returnStrictlyST #-}
58 {-# INLINE thenStrictlyST #-}
59 {-# INLINE seqStrictlyST #-}
61 {-# GENERATE_SPECS returnStrictlyST a #-}
62 returnStrictlyST :: a -> ST s a
64 {-# GENERATE_SPECS thenStrictlyST a b #-}
65 thenStrictlyST :: ST s a -> (a -> ST s b) -> ST s b
67 {-# GENERATE_SPECS seqStrictlyST a b #-}
68 seqStrictlyST :: ST s a -> ST s b -> ST s b
70 returnStrictlyST a = ST $ \ s@(S# _) -> (a, s)
72 thenStrictlyST (ST m) k = ST $ \ s -> -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
73 case (m s) of { (r, new_s) ->
74 case (k r) of { ST k2 ->
77 seqStrictlyST (ST m) (ST k) = ST $ \ s -> -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
78 case (m s) of { (_, new_s) ->
81 -- BUILT-IN: runST (see Builtin.hs)
83 unsafeInterleaveST :: ST s a -> ST s a -- ToDo: put in state-interface.tex
84 unsafeInterleaveST (ST m) = ST $ \ s ->
90 fixST :: (a -> ST s a) -> ST s a
98 -- more backward compatibility stuff:
99 listST :: [ST s a] -> ST s [a]
100 mapST :: (a -> ST s b) -> [a] -> ST s [b]
101 mapAndUnzipST :: (a -> ST s (b,c)) -> [a] -> ST s ([b],[c])
105 mapAndUnzipST = mapAndUnzipM
110 %*********************************************************
112 \subsection{The @PrimIO@ monad}
114 %*********************************************************
117 type PrimIO a = ST RealWorld a
119 fixPrimIO :: (a -> PrimIO a) -> PrimIO a
122 {-# GENERATE_SPECS unsafePerformPrimIO a #-}
123 unsafePerformPrimIO :: PrimIO a -> a
124 unsafeInterleavePrimIO :: PrimIO a -> PrimIO a
126 unsafePerformPrimIO = runST
127 unsafeInterleavePrimIO = unsafeInterleaveST
129 -- the following functions are now there for backward compatibility mostly:
131 {-# GENERATE_SPECS returnPrimIO a #-}
132 returnPrimIO :: a -> PrimIO a
134 {-# GENERATE_SPECS thenPrimIO b #-}
135 thenPrimIO :: PrimIO a -> (a -> PrimIO b) -> PrimIO b
137 {-# GENERATE_SPECS seqPrimIO b #-}
138 seqPrimIO :: PrimIO a -> PrimIO b -> PrimIO b
140 listPrimIO :: [PrimIO a] -> PrimIO [a]
141 mapPrimIO :: (a -> PrimIO b) -> [a] -> PrimIO [b]
142 mapAndUnzipPrimIO :: (a -> PrimIO (b,c)) -> [a] -> PrimIO ([b],[c])
144 {-# INLINE returnPrimIO #-}
145 {-# INLINE thenPrimIO #-}
146 {-# INLINE seqPrimIO #-}
148 returnPrimIO = return
151 listPrimIO = accumulate
153 mapAndUnzipPrimIO = mapAndUnzipM
157 %*********************************************************
159 \subsection{Ghastly return types}
161 %*********************************************************
164 data StateAndPtr# s elt = StateAndPtr# (State# s) elt
166 data StateAndChar# s = StateAndChar# (State# s) Char#
167 data StateAndInt# s = StateAndInt# (State# s) Int#
168 data StateAndWord# s = StateAndWord# (State# s) Word#
169 data StateAndFloat# s = StateAndFloat# (State# s) Float#
170 data StateAndDouble# s = StateAndDouble# (State# s) Double#
171 data StateAndAddr# s = StateAndAddr# (State# s) Addr#