module EffSTT ( -- * Basic STT type and instances STT , Ptr -- * Monadic operators , ret , bind -- * Create a reference , newPtr -- * Read a reference , readPtr -- * Write a reference , writePtr )where import qualified Data.Map as M type State = M.Map Int Int newtype Ptr = Ptr Int data STT a = STT (State -> (a, State)) ---------------------------------------------------------------- -- | Accessing State via Ptr ---------------------------------------------------------------- {-@ newPtr :: forall . n:Int -> STT <{H}, {\l -> H * l := n}> Ptr @-} newPtr :: Int -> STT Ptr newPtr n = STT $ \m0 -> let p = M.size m0 m1 = M.insert p n m0 in (Ptr p, m1) {-@ readPtr :: forall

Prop, H :: HProp>. l:Ptr -> STT <{H * l := Int

}, {\_ -> H * l := Int

}> Int

@-} readPtr :: Ptr -> STT Int readPtr (Ptr p) = STT $ \m0 -> (M.findWithDefault (error "readPtr DIES") p m0, m0) {-@ writePtr :: forall

Prop, H :: HProp>. l:Ptr -> Int

-> STT <{H * l := Int}, {\_ -> H * l := Int

}> () @-} writePtr :: Ptr -> Int -> STT () writePtr (Ptr p) n = STT $ \m0 -> ((), M.insert p n m0) ---------------------------------------------------------------- -- | Monad instance for STT ---------------------------------------------------------------- instance Monad STT where return = ret (>>=) = bind ret :: a -> STT a ret x = STT (\s0 -> (x, s0)) bind :: STT a -> (a -> STT b) -> STT b bind (STT f) k = STT $ \s0 -> let (x, s1) = f s0 STT fk = k x in fk s1 ----------------------------------------------------------------