1 \section{SST: the strict state transformer monad}
2 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #include "HsVersions.h"
8 SST(..), SST_R, FSST(..), FSST_R,
10 _runSST, sstToST, stToSST,
11 thenSST, thenSST_, returnSST,
12 thenFSST, thenFSST_, returnFSST, failFSST,
13 recoverFSST, recoverSST, fixFSST,
15 MutableVar(..), _MutableArray,
16 newMutVarSST, readMutVarSST, writeMutVarSST
19 import PreludeGlaST( MutableVar(..), _MutableArray(..), ST(..) )
21 CHK_Ubiq() -- debugging consistency check
25 data SST_R s r = SST_R r (State# s)
26 type SST s r = State# s -> SST_R s r
30 -- converting to/from ST
32 sstToST :: SST s r -> ST s r
33 stToSST :: ST s r -> SST s r
36 = case sst s of SST_R r s' -> (r, S# s')
38 = case st (S# s) of (r, S# s') -> SST_R r s'
41 -- Type of runSST should be builtin ...
42 -- runSST :: forall r. (forall s. SST s r) -> r
44 _runSST :: SST _RealWorld r -> r
45 _runSST m = case m realWorld# of SST_R r s -> r
48 thenSST :: SST s r -> (r -> State# s -> b) -> State# s -> b
49 {-# INLINE thenSST #-}
51 -- thenSST :: SST s r -> (r -> SST s r') -> SST s r'
52 -- and thenSST :: SST s r -> (r -> FSST s r' err) -> FSST s r' err
54 thenSST m k s = case m s of { SST_R r s' -> k r s' }
56 thenSST_ :: SST s r -> (State# s -> b) -> State# s -> b
57 {-# INLINE thenSST_ #-}
59 -- thenSST_ :: SST s r -> SST s r' -> SST s r'
60 -- and thenSST_ :: SST s r -> FSST s r' err -> FSST s r' err
62 thenSST_ m k s = case m s of { SST_R r s' -> k s' }
64 returnSST :: r -> SST s r
65 {-# INLINE returnSST #-}
66 returnSST r s = SST_R r s
70 \section{FSST: the failable strict state transformer monad}
71 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74 data FSST_R s r err = FSST_R_OK r (State# s)
75 | FSST_R_Fail err (State# s)
77 type FSST s r err = State# s -> FSST_R s r err
81 thenFSST :: FSST s r err -> (r -> FSST s r' err) -> FSST s r' err
82 {-# INLINE thenFSST #-}
83 thenFSST m k s = case m s of
84 FSST_R_OK r s' -> k r s'
85 FSST_R_Fail err s' -> FSST_R_Fail err s'
87 thenFSST_ :: FSST s r err -> FSST s r' err -> FSST s r' err
88 {-# INLINE thenFSST_ #-}
89 thenFSST_ m k s = case m s of
90 FSST_R_OK r s' -> k s'
91 FSST_R_Fail err s' -> FSST_R_Fail err s'
93 returnFSST :: r -> FSST s r err
94 {-# INLINE returnFSST #-}
95 returnFSST r s = FSST_R_OK r s
97 failFSST :: err -> FSST s r err
98 {-# INLINE failFSST #-}
99 failFSST err s = FSST_R_Fail err s
101 recoverFSST :: (err -> FSST s r err)
104 recoverFSST recovery_fn m s
106 FSST_R_OK r s' -> FSST_R_OK r s'
107 FSST_R_Fail err s' -> recovery_fn err s'
109 recoverSST :: (err -> SST s r)
112 recoverSST recovery_fn m s
114 FSST_R_OK r s' -> SST_R r s'
115 FSST_R_Fail err s' -> recovery_fn err s'
117 fixFSST :: (r -> FSST s r err) -> FSST s r err
121 FSST_R_OK loop _ = result
126 Here we implement mutable variables. ToDo: get rid of the array impl.
129 newMutVarSST :: a -> SST s (MutableVar s a)
131 = case (newArray# 1# init s#) of { StateAndMutableArray# s2# arr# ->
132 SST_R (_MutableArray vAR_IXS arr#) s2# }
134 vAR_IXS = error "Shouldn't access `bounds' of a MutableVar\n"
136 readMutVarSST :: MutableVar s a -> SST s a
137 readMutVarSST (_MutableArray _ var#) s#
138 = case readArray# var# 0# s# of { StateAndPtr# s2# r ->
141 writeMutVarSST :: MutableVar s a -> a -> SST s ()
142 writeMutVarSST (_MutableArray _ var#) val s#
143 = case writeArray# var# 0# val s# of { s2# ->