2020-06-20 14:51:38 +03:00
|
|
|
module Control.Monad.ST
|
2020-06-20 01:52:30 +03:00
|
|
|
|
|
|
|
import Data.IORef
|
|
|
|
|
2021-06-09 17:13:54 +03:00
|
|
|
%default total
|
2021-06-09 01:05:10 +03:00
|
|
|
|
2020-06-20 01:52:30 +03:00
|
|
|
export
|
|
|
|
data STRef : Type -> Type -> Type where
|
|
|
|
MkSTRef : IORef a -> STRef s a
|
|
|
|
|
|
|
|
export
|
|
|
|
data ST : Type -> Type -> Type where
|
|
|
|
MkST : IO a -> ST s a
|
|
|
|
|
|
|
|
export
|
|
|
|
runST : (forall s . ST s a) -> a
|
|
|
|
runST p
|
|
|
|
= let MkST prog = p {s = ()} in -- anything will do :)
|
|
|
|
unsafePerformIO prog
|
|
|
|
|
2021-06-09 17:13:54 +03:00
|
|
|
export
|
|
|
|
Functor (ST s) where
|
|
|
|
map fn (MkST st) = MkST $ fn <$> st
|
|
|
|
|
|
|
|
export
|
|
|
|
Applicative (ST s) where
|
|
|
|
pure = MkST . pure
|
|
|
|
MkST f <*> MkST a = MkST $ f <*> a
|
|
|
|
|
|
|
|
export
|
|
|
|
Monad (ST s) where
|
|
|
|
MkST p >>= k
|
|
|
|
= MkST $ do p' <- p
|
|
|
|
let MkST kp = k p'
|
|
|
|
kp
|
2020-06-20 01:52:30 +03:00
|
|
|
|
|
|
|
export
|
|
|
|
newSTRef : a -> ST s (STRef s a)
|
|
|
|
newSTRef val
|
|
|
|
= MkST $ do r <- newIORef val
|
|
|
|
pure (MkSTRef r)
|
|
|
|
|
|
|
|
%inline
|
|
|
|
export
|
|
|
|
readSTRef : STRef s a -> ST s a
|
|
|
|
readSTRef (MkSTRef r) = MkST $ readIORef r
|
|
|
|
|
|
|
|
%inline
|
|
|
|
export
|
|
|
|
writeSTRef : STRef s a -> (val : a) -> ST s ()
|
|
|
|
writeSTRef (MkSTRef r) val = MkST $ writeIORef r val
|
|
|
|
|
|
|
|
export
|
|
|
|
modifySTRef : STRef s a -> (a -> a) -> ST s ()
|
|
|
|
modifySTRef ref f
|
|
|
|
= do val <- readSTRef ref
|
|
|
|
writeSTRef ref (f val)
|