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.
19 newSTRef, readSTRef, writeSTRef,
22 newSTArray, readSTArray, writeSTArray, boundsSTArray,
23 thawSTArray, freezeSTArray, unsafeFreezeSTArray,
26 ST.unsafeIOToST, ST.stToIO,
28 strictToLazyST, lazyToStrictST
32 import qualified PrelST
34 import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
39 newtype ST s a = ST (State s -> (a, State s))
41 data State s = S# (State# s)
43 instance Functor (ST s) where
44 fmap f m = ST $ \ s ->
51 instance Monad (ST s) where
53 return a = ST $ \ s -> (a,s)
54 m >> k = m >>= \ _ -> k
65 {-# NOINLINE runST #-}
66 runST :: (forall s. ST s a) -> a
67 runST st = case st of ST the_st -> let (r,_) = the_st (S# realWorld#) in r
70 %*********************************************************
72 \subsection{Variables}
74 %*********************************************************
77 newSTRef :: a -> ST s (ST.STRef s a)
78 readSTRef :: ST.STRef s a -> ST s a
79 writeSTRef :: ST.STRef s a -> a -> ST s ()
81 newSTRef = strictToLazyST . ST.newSTRef
82 readSTRef = strictToLazyST . ST.readSTRef
83 writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
87 %*********************************************************
91 %*********************************************************
94 newtype STArray s ix elt = STArray (MutableArray s ix elt)
96 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
97 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
98 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
99 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
100 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
101 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
102 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
104 newSTArray ixs init =
105 strictToLazyST (newArray ixs init) >>= \arr ->
108 readSTArray (STArray arr) ix = strictToLazyST (readArray arr ix)
109 writeSTArray (STArray arr) ix v = strictToLazyST (writeArray arr ix v)
110 boundsSTArray (STArray arr) = boundsOfArray arr
112 strictToLazyST (thawArray arr) >>= \ marr ->
113 return (STArray marr)
115 freezeSTArray (STArray arr) = strictToLazyST (freezeArray arr)
116 unsafeFreezeSTArray (STArray arr) = strictToLazyST (unsafeFreezeArray arr)
117 unsafeThawSTArray arr =
118 strictToLazyST (unsafeThawArray arr) >>= \ marr ->
119 return (STArray marr)
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