-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Exceptions which are explicit in the type signature. -- -- Synchronous and Asynchronous exceptions which are explicit in the type -- signature. The first ones are very similar to Either and -- Control.Monad.Error.ErrorT. The second ones are used for -- System.IO.readFile and System.IO.hGetContents. This -- package is a proposal for improved exception handling in Haskell. It -- strictly separates between handling of exceptional situations (file -- not found, invalid user input, see -- http://www.haskell.org/haskellwiki/Exception) and (programming) -- errors (division by zero, index out of range, see -- http://www.haskell.org/haskellwiki/Error). Handling of the -- first one is called "exception handling", whereas handling of errors -- is better known as "debugging". -- -- For applications see the packages midi, spreadsheet, -- http-monad. -- -- Although I'm not happy with the identifier style of the Monad -- Transformer Library (partially intended for unqualified use) I have -- tried to adopt it for this library, in order to let Haskell -- programmers get accustomed easily to it. -- -- To do: Because many people requested it, we will provide a -- bracket function that frees a resource both when an exception -- and an error occurs, that is, it combines exception handling and -- debugging. However note that freeing resources in case of an error is -- dangerous and may cause further damage. @package explicit-exception @version 0.1.5 -- | Synchronous exceptions immediately abort a series of computations. We -- provide monads for describing this behaviour. In contrast to ErrorT -- from mtl or transformers package we do not pose -- restrictions on the exception type. -- -- How to tell, that a function can possibly throw more than one (kind -- of) exception? -- -- If you would use the exception type (Either ParserException -- IOError) then this is different from (Either IOError -- ParserException). Thus we recommned using type classes for -- exceptions. Then you can use one type containing all exceptions in an -- application, but the type signature still tells which exceptions are -- actually possible. Examples: -- --
-- parser :: ParserException e => ExceptionalT e ParserMonad a -- -- getLine :: IOException e => ExceptionalT e IO String -- -- fileParser :: (ParserException e, IOException e) => ExceptionalT e IO String ---- -- Unfortunately, this way you cannot remove single exceptions from the -- constraints by catching them. You can only remove all of them using -- resolve or none. For a more advanced approach, that allows -- removing exceptions constraints by some non-Haskell-98 type hackery, -- see the exception package by Joseph Iborra. module Control.Monad.Exception.Synchronous -- | Like Either, but explicitly intended for handling of -- exceptional results. In contrast to Either we do not support -- fail. Calling fail in the Exceptional monad is an -- error. This way, we do not require that an exception can be derived -- from a String, yet, we require no constraint on the exception -- type at all. data Exceptional e a Success :: a -> Exceptional e a Exception :: e -> Exceptional e a fromMaybe :: e -> Maybe a -> Exceptional e a toMaybe :: Exceptional e a -> Maybe a fromEither :: Either e a -> Exceptional e a toEither :: Exceptional e a -> Either e a -- | useful in connection with -- Control.Monad.Exception.Asynchronous.continue getExceptionNull :: Exceptional e () -> Maybe e -- | Counterpart to either for Either. switch :: (e -> b) -> (a -> b) -> Exceptional e a -> b -- | If you are sure that the value is always a Success you can tell -- that the run-time system thus making your program lazy. However, try -- to avoid this function by using catch and friends, since this -- function is partial. force :: Exceptional e a -> Exceptional e a mapException :: (e0 -> e1) -> Exceptional e0 a -> Exceptional e1 a mapExceptional :: (e0 -> e1) -> (a -> b) -> Exceptional e0 a -> Exceptional e1 b throw :: e -> Exceptional e a assert :: e -> Bool -> Exceptional e () catch :: Exceptional e0 a -> (e0 -> Exceptional e1 a) -> Exceptional e1 a resolve :: (e -> a) -> Exceptional e a -> a -- | like ErrorT, but ExceptionalT is the better name in order to -- distinguish from real (programming) errors newtype ExceptionalT e m a ExceptionalT :: m (Exceptional e a) -> ExceptionalT e m a runExceptionalT :: ExceptionalT e m a -> m (Exceptional e a) fromErrorT :: Monad m => ErrorT e m a -> ExceptionalT e m a toErrorT :: Monad m => ExceptionalT e m a -> ErrorT e m a fromEitherT :: Monad m => m (Either e a) -> ExceptionalT e m a toEitherT :: Monad m => ExceptionalT e m a -> m (Either e a) -- | see force forceT :: Monad m => ExceptionalT e m a -> ExceptionalT e m a mapExceptionT :: Monad m => (e0 -> e1) -> ExceptionalT e0 m a -> ExceptionalT e1 m a mapExceptionalT :: (m (Exceptional e0 a) -> n (Exceptional e1 b)) -> ExceptionalT e0 m a -> ExceptionalT e1 n b throwT :: Monad m => e -> ExceptionalT e m a assertT :: Monad m => e -> Bool -> ExceptionalT e m () catchT :: Monad m => ExceptionalT e0 m a -> (e0 -> ExceptionalT e1 m a) -> ExceptionalT e1 m a -- | If the enclosed monad has custom exception facilities, they could skip -- the cleanup code. Make sure, that this cannot happen by choosing an -- appropriate monad. bracketT :: Monad m => ExceptionalT e m h -> (h -> ExceptionalT e m ()) -> (h -> ExceptionalT e m a) -> ExceptionalT e m a resolveT :: Monad m => (e -> m a) -> ExceptionalT e m a -> m a tryT :: Monad m => ExceptionalT e m a -> m (Exceptional e a) -- | Repeat an action until an exception occurs. Initialize the result with -- empty and add new elements using cons (e.g. -- [] and (:)). The exception handler decides whether -- the terminating exception is re-raised (Just) or catched -- (Nothing). manyT :: Monad m => (e0 -> Maybe e1) -> (a -> b -> b) -> b -> ExceptionalT e0 m a -> ExceptionalT e1 m b manyMonoidT :: (Monad m, Monoid a) => (e0 -> Maybe e1) -> ExceptionalT e0 m a -> ExceptionalT e1 m a instance (Show e, Show a) => Show (Exceptional e a) instance (Eq e, Eq a) => Eq (Exceptional e a) instance MonadTrans (ExceptionalT e) instance MonadFix m => MonadFix (ExceptionalT e m) instance Monad m => Monad (ExceptionalT e m) instance Applicative m => Applicative (ExceptionalT e m) instance Functor m => Functor (ExceptionalT e m) instance MonadFix (Exceptional e) instance Monad (Exceptional e) instance Applicative (Exceptional e) instance Functor (Exceptional e) -- | Asynchronous exceptions can occur during the construction of a lazy -- data structure. They are represented by a lazy data structure itself. -- -- TODO: -- --
-- import Data.Monoid (Endo, appEndo, ) -- import Control.Exception (try, ) -- import qualified Control.Monad.Exception.Synchronous as Sync ---- --
-- fmap (flip appEndo []) $ manyMonoidT (fromSynchronousMonoidT $ fmap (Endo . (:)) $ Sync.fromEitherT $ try getChar) ---- -- If you want Lazy IO you must additionally convert getChar to -- LazyIO monad. manyMonoidT :: (Monad m, Monoid a) => ExceptionalT e m a -> ExceptionalT e m a -- | Scan x using the decons function and run an action -- with synchronous exceptions for each element fetched from x. -- Each invocation of an element action may stop this function due to an -- exception. If all element actions can be performed successfully and if -- there is an asynchronous exception then at the end this exception is -- raised as synchronous exception. decons function might be -- Data.List.HT.viewL. processToSynchronousT_ :: Monad m => (b -> Maybe (a, b)) -> (a -> ExceptionalT e m ()) -> Exceptional e b -> ExceptionalT e m () appendM :: (Monad m, Monoid a) => m (Exceptional e a) -> m (Exceptional e a) -> m (Exceptional e a) continueM :: (Monad m, Monoid a) => m (Maybe e) -> m (Exceptional e a) -> m (Exceptional e a) instance (Show e, Show a) => Show (Exceptional e a) instance (Monad m, Monoid a) => Monoid (ExceptionalT e m a) instance Functor m => Functor (ExceptionalT e m) instance Functor (Exceptional e) instance Monoid a => Monoid (Exceptional e a)