lhs2tex-1.21: src/StateT.lhs
%-------------------------------= --------------------------------------------
\subsection{State transformer}
%-------------------------------= --------------------------------------------
%if codeOnly || showModuleHeader
> {-# LANGUAGE GeneralizedNewtypeDeriving #-}
> {-# OPTIONS_GHC -fno-warn-unused-imports #-}
> module StateT ( module StateT )
> where
>
> import Control.Applicative -- only needed for older GHCs
> import Control.Monad.Except
> import Control.Monad.State
%endif
|IO| with internal state and error handling.
%if style == math
%format MkXIO (m) = m
%format unXIO (m) = m
%endif
> newtype XIO exc st a = MkXIO (ExceptT exc (StateT st IO) a)
> deriving (Functor, Applicative, Monad, MonadIO, MonadState st, MonadError exc)
-- XIO exc st a ~= StateT st IO (Either exc a)
-- ~= ErrorT exc (StateT st IO) a
%if style /= math
> unXIO :: XIO exc st a -> ExceptT exc (StateT st IO) a
> unXIO (MkXIO f) = f
%endif
\NB The state is preserved upon failure.
> toIO :: XIO exc st a -> IO a
> toIO (MkXIO m) = do
> (r, _) <- runStateT (runExceptT m)
> (error "no initial state supplied")
> case r of Left _ -> error "unhandled error"
> Right x -> return x
> fromEither :: Either exc a -> XIO exc st a
> fromEither = either throwError return