2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[module_ST]{The State Transformer Monad, @ST@}
7 {-# OPTIONS -fno-implicit-prelude #-}
13 runST, -- :: (forall s. ST s a) -> a
14 fixST, -- :: (a -> ST s a) -> ST s a
18 -- ST is one, so you'll likely need some Monad bits
22 newSTRef, readSTRef, writeSTRef,
25 newSTArray, readSTArray, writeSTArray, boundsSTArray,
26 thawSTArray, freezeSTArray, unsafeFreezeSTArray,
33 #define MutableVar Ref
34 #define readVar primReadRef
35 #define writeVar primWriteRef
36 #define newVar primNewRef
40 import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
47 %*********************************************************
49 \subsection{Variables}
51 %*********************************************************
54 newtype STRef s a = STRef (MutableVar s a)
57 newSTRef :: a -> ST s (STRef s a)
58 newSTRef v = newVar v >>= \ var -> return (STRef var)
60 readSTRef :: STRef s a -> ST s a
61 readSTRef (STRef var) = readVar var
63 writeSTRef :: STRef s a -> a -> ST s ()
64 writeSTRef (STRef var) v = writeVar var v
67 %*********************************************************
71 %*********************************************************
74 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
75 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
76 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
77 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
78 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
79 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
80 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
83 data STArray s ix elt = STArray (ix,ix) (PrimMutableArray s elt)
86 newSTArray ixs elt = do
87 { arr <- primNewArray (rangeSize ixs) elt
88 ; return (STArray ixs arr)
91 boundsSTArray (STArray ixs arr) = ixs
92 readSTArray (STArray ixs arr) ix = primReadArray arr (index ixs ix)
93 writeSTArray (STArray ixs arr) ix elt = primWriteArray arr (index ixs ix) elt
94 freezeSTArray (STArray ixs arr) = do
95 { arr' <- primFreezeArray arr
96 ; return (Array ixs arr')
99 unsafeFreezeSTArray (STArray ixs arr) = do
100 { arr' <- primUnsafeFreezeArray arr
101 ; return (Array ixs arr')
104 thawSTArray (Array ixs arr) = do
105 { arr' <- primThawArray arr
106 ; return (STArray ixs arr')
109 primFreezeArray :: PrimMutableArray s a -> ST s (PrimArray a)
110 primFreezeArray arr = do
111 { let n = primSizeMutableArray arr
112 ; arr' <- primNewArray n arrEleBottom
113 ; mapM_ (copy arr arr') [0..n-1]
114 ; primUnsafeFreezeArray arr'
117 copy arr arr' i = do { x <- primReadArray arr i; primWriteArray arr' i x }
118 arrEleBottom = error "primFreezeArray: panic"
120 primThawArray :: PrimArray a -> ST s (PrimMutableArray s a)
121 primThawArray arr = do
122 { let n = primSizeArray arr
123 ; arr' <- primNewArray n arrEleBottom
124 ; mapM_ (copy arr arr') [0..n-1]
128 copy arr arr' i = primWriteArray arr' i (primIndexArray arr i)
129 arrEleBottom = error "primFreezeArray: panic"
131 newtype STArray s ix elt = STArray (MutableArray s ix elt)
135 newArray ixs elt >>= \arr ->
138 boundsSTArray (STArray arr) = boundsOfArray arr
140 readSTArray (STArray arr) ix = readArray arr ix
142 writeSTArray (STArray arr) ix elt = writeArray arr ix elt
144 thawSTArray arr = thawArray arr >>= \starr -> return (STArray starr)
146 freezeSTArray (STArray arr) = freezeArray arr
148 unsafeFreezeSTArray (STArray arr) = unsafeFreezeArray arr