2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
5 \section[LazyST]{The Lazy State Transformer Monad, @LazyST@}
7 This module presents an identical interface to ST, but the underlying
8 implementation of the state thread is lazy.
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,
29 ST.unsafeIOToST, ST.stToIO,
31 strictToLazyST, lazyToStrictST
35 import qualified PrelST
37 import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
42 newtype ST s a = ST (State s -> (a, State s))
44 data State s = S# (State# s)
46 instance Functor (ST s) where
47 fmap f m = ST $ \ s ->
54 instance Monad (ST s) where
56 return a = ST $ \ s -> (a,s)
57 m >> k = m >>= \ _ -> k
68 {-# NOINLINE runST #-}
69 runST :: (forall s. ST s a) -> a
70 runST st = case st of ST the_st -> let (r,_) = the_st (S# realWorld#) in r
73 %*********************************************************
75 \subsection{Variables}
77 %*********************************************************
80 newSTRef :: a -> ST s (ST.STRef s a)
81 readSTRef :: ST.STRef s a -> ST s a
82 writeSTRef :: ST.STRef s a -> a -> ST s ()
84 newSTRef = strictToLazyST . ST.newSTRef
85 readSTRef = strictToLazyST . ST.readSTRef
86 writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
90 %*********************************************************
94 %*********************************************************
97 newtype STArray s ix elt = STArray (MutableArray s ix elt)
99 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
100 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
101 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
102 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
103 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
104 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
105 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
107 newSTArray ixs init =
108 strictToLazyST (newArray ixs init) >>= \arr ->
111 readSTArray (STArray arr) ix = strictToLazyST (readArray arr ix)
112 writeSTArray (STArray arr) ix v = strictToLazyST (writeArray arr ix v)
113 boundsSTArray (STArray arr) = boundsOfArray arr
115 strictToLazyST (thawArray arr) >>= \ marr ->
116 return (STArray marr)
118 freezeSTArray (STArray arr) = strictToLazyST (freezeArray arr)
119 unsafeFreezeSTArray (STArray arr) = strictToLazyST (unsafeFreezeArray arr)
121 strictToLazyST :: PrelST.ST s a -> ST s a
122 strictToLazyST m = ST $ \s ->
124 pr = case s of { S# s# -> PrelST.liftST m s# }
125 r = case pr of { PrelST.STret _ v -> v }
126 s' = case pr of { PrelST.STret s2# _ -> S# s2# }
130 lazyToStrictST :: ST s a -> PrelST.ST s a
131 lazyToStrictST (ST m) = PrelST.ST $ \s ->
132 case (m (S# s)) of (a, S# s') -> (# s', a #)
134 unsafeInterleaveST :: ST s a -> ST s a
135 unsafeInterleaveST = strictToLazyST . ST.unsafeInterleaveST . lazyToStrictST