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 strictToLazyST, lazyToStrictST
33 import qualified PrelST
35 import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
40 newtype ST s a = ST (PrelST.State s -> (a,PrelST.State s))
42 instance Functor (ST s) where
43 fmap f m = ST $ \ s ->
50 instance Monad (ST s) where
52 return a = ST $ \ s -> (a,s)
53 m >> k = m >>= \ _ -> k
64 {-# NOINLINE runST #-}
65 runST :: (forall s. ST s a) -> a
66 runST st = case st of ST the_st -> let (r,_) = the_st (PrelST.S# realWorld#) in r
69 %*********************************************************
71 \subsection{Variables}
73 %*********************************************************
76 newSTRef :: a -> ST s (ST.STRef s a)
77 readSTRef :: ST.STRef s a -> ST s a
78 writeSTRef :: ST.STRef s a -> a -> ST s ()
80 newSTRef = strictToLazyST . ST.newSTRef
81 readSTRef = strictToLazyST . ST.readSTRef
82 writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
85 %*********************************************************
89 %*********************************************************
92 newtype STArray s ix elt = STArray (MutableArray s ix elt)
94 newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
95 readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
96 writeSTArray :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
97 boundsSTArray :: Ix ix => STArray s ix elt -> (ix, ix)
98 thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
99 freezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
100 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
102 newSTArray ixs init =
103 strictToLazyST (newArray ixs init) >>= \arr ->
106 readSTArray (STArray arr) ix = strictToLazyST (readArray arr ix)
107 writeSTArray (STArray arr) ix v = strictToLazyST (writeArray arr ix v)
108 boundsSTArray (STArray arr) = boundsOfArray arr
110 strictToLazyST (thawArray arr) >>= \ marr ->
111 return (STArray marr)
113 freezeSTArray (STArray arr) = strictToLazyST (freezeArray arr)
114 unsafeFreezeSTArray (STArray arr) = strictToLazyST (unsafeFreezeArray arr)
116 strictToLazyST :: PrelST.ST s a -> ST s a
117 strictToLazyST m = ST $ \s ->
119 pr = case s of { PrelST.S# s# -> PrelST.liftST m s# }
120 r = case pr of { PrelST.STret _ v -> v }
121 s' = case pr of { PrelST.STret s2# _ -> PrelST.S# s2# }
125 lazyToStrictST :: ST s a -> PrelST.ST s a
126 lazyToStrictST (ST m) = PrelST.ST $ \s ->
127 case (m (PrelST.S# s)) of (a, PrelST.S# s') -> (# s', a #)
129 unsafeInterleaveST :: ST s a -> ST s a
130 unsafeInterleaveST = strictToLazyST . ST.unsafeInterleaveST . lazyToStrictST