module DDC.Control.Monad.Check
( CheckM (..)
, throw
, runCheck
, evalCheck
, get
, put)
where
import Control.Applicative
import Control.Monad
data CheckM s err a
= CheckM (s -> (s, Either err a))
instance Functor (CheckM s err) where
fmap = liftM
instance Applicative (CheckM s err) where
(<*>) = ap
pure = return
instance Monad (CheckM s err) where
return !x
= CheckM (\s -> (s, Right x))
(>>=) !(CheckM f) !g
= CheckM $ \s
-> case f s of
(s', Left err) -> (s', Left err)
(s', Right x) -> s `seq` x `seq` runCheck s' (g x)
runCheck :: s -> CheckM s err a -> (s, Either err a)
runCheck s (CheckM f) = f s
evalCheck :: s -> CheckM s err a -> Either err a
evalCheck s m = snd $ runCheck s m
throw :: err -> CheckM s err a
throw !e = CheckM $ \s -> (s, Left e)
get :: CheckM s err s
get = CheckM $ \s -> (s, Right s)
put :: s -> CheckM s err ()
put s
= CheckM $ \_ -> (s, Right ())