2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[module_ST]{The State Transformer Monad, @ST@}
7 {-# OPTIONS -fno-implicit-prelude #-}
11 -- ToDo: review this interface; I'm avoiding gratuitous changes for now
17 -- ST is one, so you'll likely need some Monad bits
20 thenST, seqST, returnST, listST, fixST, runST, unsafeInterleaveST,
23 returnLazyST, thenLazyST, seqLazyST,
26 newVar, readVar, writeVar, sameVar,
29 newArray, readArray, writeArray, sameMutableArray
33 import IOBase ( error ) -- [Source not needed]
36 import PrelBase ( Int, Bool, ($), ()(..) )
37 import GHC ( newArray#, readArray#, writeArray#, sameMutableArray#, sameMutableByteArray# )
42 %*********************************************************
44 \subsection{Variables}
46 %*********************************************************
49 -- in ArrBase: type MutableVar s a = MutableArray s Int a
51 newVar :: a -> ST s (MutableVar s a)
52 readVar :: MutableVar s a -> ST s a
53 writeVar :: MutableVar s a -> a -> ST s ()
54 sameVar :: MutableVar s a -> MutableVar s a -> Bool
56 newVar init = ST $ \ (S# s#) ->
57 case (newArray# 1# init s#) of { StateAndMutableArray# s2# arr# ->
58 (MutableArray vAR_IXS arr#, S# s2#) }
60 vAR_IXS = error "newVar: Shouldn't access `bounds' of a MutableVar\n"
62 readVar (MutableArray _ var#) = ST $ \ (S# s#) ->
63 case readArray# var# 0# s# of { StateAndPtr# s2# r ->
66 writeVar (MutableArray _ var#) val = ST $ \ (S# s#) ->
67 case writeArray# var# 0# val s# of { s2# ->
70 sameVar (MutableArray _ var1#) (MutableArray _ var2#)
71 = sameMutableArray# var1# var2#
76 sameMutableArray :: MutableArray s ix elt -> MutableArray s ix elt -> Bool
77 sameMutableByteArray :: MutableByteArray s ix -> MutableByteArray s ix -> Bool
79 sameMutableArray (MutableArray _ arr1#) (MutableArray _ arr2#)
80 = sameMutableArray# arr1# arr2#
82 sameMutableByteArray (MutableByteArray _ arr1#) (MutableByteArray _ arr2#)
83 = sameMutableByteArray# arr1# arr2#
86 Lazy monad combinators, the @Monad@ instance for @ST@
87 uses the strict variant:
90 returnLazyST :: a -> ST s a
91 returnLazyST a = ST (\ s -> (a, s))
93 thenLazyST :: ST s a -> (a -> ST s b) -> ST s b
103 seqLazyST :: ST s a -> ST s b -> ST s b