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 (PrelST.State s -> (a,PrelST.State s))
44 instance Functor (ST s) where
45 fmap f m = ST $ \ s ->
52 instance Monad (ST s) where
54 return a = ST $ \ s -> (a,s)
55 m >> k = m >>= \ _ -> k
66 {-# NOINLINE runST #-}
67 runST :: (forall s. ST s a) -> a
68 runST st = case st of ST the_st -> let (r,_) = the_st (PrelST.S# realWorld#) in r
71 %*********************************************************
73 \subsection{Variables}
75 %*********************************************************
78 newSTRef :: a -> ST s (ST.STRef s a)
79 readSTRef :: ST.STRef s a -> ST s a
80 writeSTRef :: ST.STRef s a -> a -> ST s ()
82 newSTRef = strictToLazyST . ST.newSTRef
83 readSTRef = strictToLazyST . ST.readSTRef
84 writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
88 %*********************************************************
92 %*********************************************************
95 newtype STArray s ix elt = STArray (MutableArray s ix elt)
97 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
98 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
99 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
100 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
101 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
102 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
103 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
105 newSTArray ixs init =
106 strictToLazyST (newArray ixs init) >>= \arr ->
109 readSTArray (STArray arr) ix = strictToLazyST (readArray arr ix)
110 writeSTArray (STArray arr) ix v = strictToLazyST (writeArray arr ix v)
111 boundsSTArray (STArray arr) = boundsOfArray arr
113 strictToLazyST (thawArray arr) >>= \ marr ->
114 return (STArray marr)
116 freezeSTArray (STArray arr) = strictToLazyST (freezeArray arr)
117 unsafeFreezeSTArray (STArray arr) = strictToLazyST (unsafeFreezeArray arr)
119 strictToLazyST :: PrelST.ST s a -> ST s a
120 strictToLazyST m = ST $ \s ->
122 pr = case s of { PrelST.S# s# -> PrelST.liftST m s# }
123 r = case pr of { PrelST.STret _ v -> v }
124 s' = case pr of { PrelST.STret s2# _ -> PrelST.S# s2# }
128 lazyToStrictST :: ST s a -> PrelST.ST s a
129 lazyToStrictST (ST m) = PrelST.ST $ \s ->
130 case (m (PrelST.S# s)) of (a, PrelST.S# s') -> (# s', a #)
132 unsafeInterleaveST :: ST s a -> ST s a
133 unsafeInterleaveST = strictToLazyST . ST.unsafeInterleaveST . lazyToStrictST