4c44e30ab456864b259b40ed5905ea29ceb179da
[ghc-hetmet.git] / ghc / lib / glaExts / LazyST.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
3 %
4
5 \section[LazyST]{The Lazy State Transformer Monad, @LazyST@}
6
7 This module presents an identical interface to ST, but the underlying
8 implementation of the state thread is lazy.
9
10 \begin{code}
11 module LazyST (
12
13         ST,
14
15         unsafeInterleaveST,
16
17         -- ST is one, so you'll likely need some Monad bits
18         module Monad,
19
20         ST.STRef,
21         newSTRef, readSTRef, writeSTRef,
22
23         STArray,
24         newSTArray, readSTArray, writeSTArray, boundsSTArray, 
25         thawSTArray, freezeSTArray, unsafeFreezeSTArray, 
26         Ix,
27
28         strictToLazyST, lazyToStrictST
29     ) where
30
31 import qualified ST
32 import qualified STBase
33 import ArrBase
34 import qualified Unsafe   ( unsafeInterleaveST )
35 import PrelBase ( Eq(..), Int, Bool, ($), ()(..) )
36 import Monad
37 import Ix
38
39 newtype ST s a = ST (STBase.State s -> (a,STBase.State s))
40
41 instance Monad (ST s) where
42
43         return a = ST $ \ s -> (a,s)
44         m >> k   =  m >>= \ _ -> k
45
46         (ST m) >>= k
47          = ST $ \ s ->
48            let
49              (r,new_s) = m s
50              ST k_a = k r
51            in
52            k_a new_s
53 \end{code}
54
55 %*********************************************************
56 %*                                                      *
57 \subsection{Variables}
58 %*                                                      *
59 %*********************************************************
60
61 \begin{code}
62 newSTRef   :: a -> ST s (ST.STRef s a)
63 readSTRef  :: ST.STRef s a -> ST s a
64 writeSTRef :: ST.STRef s a -> a -> ST s ()
65
66 newSTRef   = strictToLazyST . ST.newSTRef
67 readSTRef  = strictToLazyST . ST.readSTRef
68 writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
69 \end{code}
70
71 %*********************************************************
72 %*                                                      *
73 \subsection{Arrays}
74 %*                                                      *
75 %*********************************************************
76
77 \begin{code}
78 newtype STArray s ix elt = STArray (MutableArray s ix elt)
79
80 newSTArray          :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
81 readSTArray         :: Ix ix => STArray s ix elt -> ix -> ST s elt 
82 writeSTArray        :: Ix ix => STArray s ix elt -> ix -> elt -> ST s () 
83 boundsSTArray       :: Ix ix => STArray s ix elt -> (ix, ix)  
84 thawSTArray         :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
85 freezeSTArray       :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
86 unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
87
88 newSTArray ixs init     = 
89            strictToLazyST (newArray ixs init) >>= \arr ->
90            return (STArray arr)
91
92 readSTArray (STArray arr) ix = strictToLazyST (readArray arr ix)
93 writeSTArray (STArray arr) ix v = strictToLazyST (writeArray arr ix v)
94 boundsSTArray (STArray arr) = boundsOfArray arr
95 thawSTArray arr = 
96             strictToLazyST (thawArray arr) >>= \arr -> 
97             return (STArray arr)
98 freezeSTArray (STArray arr) = strictToLazyST (freezeArray arr)
99 unsafeFreezeSTArray (STArray arr) = strictToLazyST (unsafeFreezeArray arr)
100
101 strictToLazyST :: STBase.ST s a -> ST s a
102 strictToLazyST (STBase.ST m) = ST $ \s ->
103         let 
104             STBase.S# s# = s
105             STBase.STret s2# r = m s# 
106         in
107         (r, STBase.S# s2#)
108
109 lazyToStrictST :: ST s a -> STBase.ST s a
110 lazyToStrictST (ST m) = STBase.ST $ \s ->
111         case (m (STBase.S# s)) of (a, STBase.S# s') -> STBase.STret s' a
112
113 unsafeInterleaveST :: ST s a -> ST s a
114 unsafeInterleaveST = strictToLazyST . ST.unsafeInterleaveST . lazyToStrictST
115
116 \end{code}