2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[module_ST]{The State Transformer Monad, @ST@}
7 {-# OPTIONS -fno-implicit-prelude #-}
11 ST -- abstract, instance of Functor, Monad.
12 , runST -- :: (forall s. ST s a) -> a
13 , fixST -- :: (a -> ST s a) -> ST s a
14 , unsafeInterleaveST -- :: ST s a -> ST s a
33 -- no 'good' reason, just doesn't support it right now.
41 #define MutableVar Ref
42 #define readVar primReadRef
43 #define writeVar primWriteRef
44 #define newVar primNewRef
48 import PrelBase ( Eq(..), Int, Bool, ($), ()(..), unsafeCoerce# )
49 import PrelIOBase ( IO(..), stToIO )
56 %*********************************************************
58 \subsection{Variables}
60 %*********************************************************
63 newtype STRef s a = STRef (MutableVar s a)
66 newSTRef :: a -> ST s (STRef s a)
67 newSTRef v = newVar v >>= \ var -> return (STRef var)
69 readSTRef :: STRef s a -> ST s a
70 readSTRef (STRef var) = readVar var
72 writeSTRef :: STRef s a -> a -> ST s ()
73 writeSTRef (STRef var) v = writeVar var v
76 %*********************************************************
80 %*********************************************************
83 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
84 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
85 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
86 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
87 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
88 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
89 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
92 -- see export list comment..
93 unsafeThawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
97 data STArray s ix elt = STArray (ix,ix) (PrimMutableArray s elt)
100 newSTArray ixs elt = do
101 { arr <- primNewArray (rangeSize ixs) elt
102 ; return (STArray ixs arr)
105 boundsSTArray (STArray ixs arr) = ixs
106 readSTArray (STArray ixs arr) ix = primReadArray arr (index ixs ix)
107 writeSTArray (STArray ixs arr) ix elt = primWriteArray arr (index ixs ix) elt
108 freezeSTArray (STArray ixs arr) = do
109 { arr' <- primFreezeArray arr
110 ; return (Array ixs arr')
113 unsafeFreezeSTArray (STArray ixs arr) = do
114 { arr' <- primUnsafeFreezeArray arr
115 ; return (Array ixs arr')
118 thawSTArray (Array ixs arr) = do
119 { arr' <- primThawArray arr
120 ; return (STArray ixs arr')
123 primFreezeArray :: PrimMutableArray s a -> ST s (PrimArray a)
124 primFreezeArray arr = do
125 { let n = primSizeMutableArray arr
126 ; arr' <- primNewArray n arrEleBottom
127 ; mapM_ (copy arr arr') [0..n-1]
128 ; primUnsafeFreezeArray arr'
131 copy arr arr' i = do { x <- primReadArray arr i; primWriteArray arr' i x }
132 arrEleBottom = error "primFreezeArray: panic"
134 primThawArray :: PrimArray a -> ST s (PrimMutableArray s a)
135 primThawArray arr = do
136 { let n = primSizeArray arr
137 ; arr' <- primNewArray n arrEleBottom
138 ; mapM_ (copy arr arr') [0..n-1]
142 copy arr arr' i = primWriteArray arr' i (primIndexArray arr i)
143 arrEleBottom = error "primFreezeArray: panic"
145 newtype STArray s ix elt = STArray (MutableArray s ix elt)
149 newArray ixs elt >>= \arr ->
152 boundsSTArray (STArray arr) = boundsOfArray arr
154 readSTArray (STArray arr) ix = readArray arr ix
156 writeSTArray (STArray arr) ix elt = writeArray arr ix elt
158 thawSTArray arr = thawArray arr >>= \starr -> return (STArray starr)
160 freezeSTArray (STArray arr) = freezeArray arr
162 unsafeFreezeSTArray (STArray arr) = unsafeFreezeArray arr
163 unsafeThawSTArray arr = unsafeThawArray arr >>= \ marr -> return (STArray marr)
170 unsafeIOToST :: IO a -> ST s a
172 unsafeIOToST = primUnsafeCoerce
174 unsafeIOToST (IO io) = ST $ \ s ->
175 case ((unsafeCoerce# io) s) of
176 (# new_s, a #) -> unsafeCoerce# (STret new_s a)
177 -- IOfail new_s e -> error ("I/O Error (unsafeIOToST): " ++ showsPrec 0 e "\n")