{-# LANGUAGE GeneralisedNewtypeDeriving #-} module Monad( App ,module Control.Monad.Fail ,module Control.Monad.IO.Class ,throwE ,except ,runApp ) where import qualified Control.Monad.Trans.Except as T import Control.Monad.Fail import Control.Monad.IO.Class -- We need this type isomorphism, because we want a different -- MonadFail implementation, if someone knows how to do this -- without writing the isomorphism out explicitly for all -- the other instances, (or without scary GeneralisedNewtypeDeriving) -- I would be happy newtype App a = App { runApp' :: T.ExceptT String IO a} deriving (Functor, Applicative, Monad, MonadIO) instance MonadFail App where fail = throwE -- reimplementing ExceptT interface -- I would love not to have to do this but I don't know how throwE :: String -> App a throwE = App . T.throwE except :: Either String a -> App a except = App . T.except runApp :: App a -> IO (Either String a) runApp = T.runExceptT . runApp'