content: %-------------------------------=  --------------------------------------------
  \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
  