explicit-exception 0.0.1 → 0.0.2
raw patch · 3 files changed
+70/−20 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Monad.Exception.Asynchronous: append :: (Monoid a) => Exceptional e a -> Exceptional e a -> Exceptional e a
+ Control.Monad.Exception.Asynchronous: continue :: (Monoid a) => Maybe e -> Exceptional e a -> Exceptional e a
+ Control.Monad.Exception.Asynchronous: fromSynchronousMonoid :: (Monoid a) => Exceptional e a -> Exceptional e a
+ Control.Monad.Exception.Asynchronous: throwMonoid :: (Monoid a) => e -> Exceptional e a
+ Control.Monad.Exception.Synchronous: fromEitherT :: (Monad m) => m (Either e a) -> ExceptionalT e m a
+ Control.Monad.Exception.Synchronous: getExceptionNull :: Exceptional e () -> Maybe e
+ Control.Monad.Exception.Synchronous: toEitherT :: (Monad m) => ExceptionalT e m a -> m (Either e a)
Files
- explicit-exception.cabal +1/−1
- src/Control/Monad/Exception/Asynchronous.hs +50/−14
- src/Control/Monad/Exception/Synchronous.hs +19/−5
explicit-exception.cabal view
@@ -1,5 +1,5 @@ Name: explicit-exception-Version: 0.0.1+Version: 0.0.2 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>
src/Control/Monad/Exception/Asynchronous.hs view
@@ -17,6 +17,7 @@ import Data.Traversable (Traversable, ) import Data.Foldable (Foldable, ) -}+import Data.Monoid(Monoid, mappend, mempty, ) import Prelude hiding (sequence) @@ -67,16 +68,24 @@ fromSynchronousNull :: Sync.Exceptional e () -> Exceptional e () fromSynchronousNull = fromSynchronous () +fromSynchronousMonoid :: Monoid a =>+ Sync.Exceptional e a -> Exceptional e a+fromSynchronousMonoid = fromSynchronous mempty++ toSynchronous :: Exceptional e a -> Sync.Exceptional e a toSynchronous (Exceptional me a) = maybe (Sync.Success a) Sync.Exception me throw :: e -> Exceptional e ()-throw e = Exceptional (Just e) ()+throw e = broken e () +throwMonoid :: Monoid a => e -> Exceptional e a+throwMonoid e = broken e mempty + {- | Repeat an action with synchronous exceptions until an exception occurs. Combine all atomic results using the @bind@ function.@@ -93,13 +102,13 @@ Sync.ExceptionalT e m a {- ^ atomic action to repeat -} -> m (Exceptional e b) manySynchronousT defer cons empty action =- let recurse =+ let recourse = liftM force $ defer $ do r <- Sync.tryT action case r of Sync.Exception e -> return (Exceptional (Just e) empty)- Sync.Success x -> liftM (fmap (cons x)) recurse- in recurse+ Sync.Success x -> liftM (fmap (cons x)) recourse+ in recourse {- | Scan @x@ using the @decons@ function@@ -118,12 +127,12 @@ Exceptional e b {- ^ value @x@ of type @b@ with asynchronous exception -} -> Sync.ExceptionalT e m () processToSynchronousT_ decons action (Exceptional me x) =- let recurse b0 =+ let recourse b0 = maybe (maybe (return ()) Sync.throwT me)- (\(a,b1) -> action a >> recurse b1)+ (\(a,b1) -> action a >> recourse b1) (decons b0)- in recurse x+ in recourse x -- ** handling of special result types@@ -141,17 +150,46 @@ (a -> b -> c) -> Exceptional e [a] -> Exceptional e [b] -> Exceptional e [c] zipWith f (Exceptional ea a0) (Exceptional eb b0) =- let recurse (a:as) (b:bs) =+ let recourse (a:as) (b:bs) = fmap (f a b :) (recurseF as bs)- recurse as _ =+ recourse as _ = Exceptional (case as of [] -> mplus ea eb; _ -> eb) []- recurseF as bs = force $ recurse as bs+ recurseF as bs = force $ recourse as bs in recurseF a0 b0 +infixr 1 `append`, `continue`++{- |+This is an example for application specific handling of result values.+Assume you obtain two lazy lists say from 'readFile'+and you want to append their contents.+If the first stream ends with an exception,+this exception is kept+and the second stream is not touched.+If the first stream can be read successfully,+the second one is appended until stops.+-}+append ::+ Monoid a =>+ Exceptional e a -> Exceptional e a -> Exceptional e a+append (Exceptional ea a) b =+ fmap (mappend a) $ continue ea b++continue ::+ Monoid a =>+ Maybe e -> Exceptional e a -> Exceptional e a+continue ea b =+ force $+ case ea of+-- Just e -> throwMonoid e+ Just _ -> Exceptional ea mempty+ Nothing -> b++ {- | construct Exceptional constructor lazily -} force :: Exceptional e a -> Exceptional e a-force (~(Exceptional e a)) = Exceptional e a+force ~(Exceptional e a) = Exceptional e a {-@@ -163,9 +201,7 @@ -} instance Functor (Exceptional e) where- fmap f x =- case x of- ~(Exceptional e a) -> Exceptional e (f a)+ fmap f ~(Exceptional e a) = Exceptional e (f a) {- Foldable instance would allow to strip off the exception too easily.
src/Control/Monad/Exception/Synchronous.hs view
@@ -38,6 +38,14 @@ Success a -> Right a Exception e -> Left e +-- | useful in connection with 'Control.Monad.Exception.Asynchronous.continue'+getExceptionNull :: Exceptional e () -> Maybe e+getExceptionNull x =+ case x of+ Success _ -> Nothing+ Exception e -> Just e++ {- | If you are sure that the value is always a 'Success' you can tell that the run-time system@@ -127,11 +135,17 @@ fromErrorT :: Monad m => ErrorT e m a -> ExceptionalT e m a-fromErrorT = ExceptionalT . liftM fromEither . runErrorT+fromErrorT = fromEitherT . runErrorT toErrorT :: Monad m => ExceptionalT e m a -> ErrorT e m a-toErrorT = ErrorT . liftM toEither . runExceptionalT+toErrorT = ErrorT . toEitherT +fromEitherT :: Monad m => m (Either e a) -> ExceptionalT e m a+fromEitherT = ExceptionalT . liftM fromEither++toEitherT :: Monad m => ExceptionalT e m a -> m (Either e a)+toEitherT = liftM toEither . runExceptionalT+ {- | see 'force' -}@@ -210,12 +224,12 @@ ExceptionalT e0 m a {- ^ atomic action to repeat -} -> ExceptionalT e1 m b manyT handler cons empty action =- let recurse =+ let recourse = do r <- lift $ tryT action case r of Exception e -> maybe (return empty) throwT (handler e)- Success x -> liftM (cons x) recurse- in recurse+ Success x -> liftM (cons x) recourse+ in recourse