-- 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://wiki.haskell.org/Exception) and (programming) errors -- (division by zero, index out of range, see -- http://wiki.haskell.org/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. -- -- See also: unexceptionalio @package explicit-exception @version 0.2 -- | 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 ---- -- You can remove single exceptions from the set, but with Haskell 98 you -- need instances for all the other constraints in the exception -- constraint set. There is a more advanced approach, that allows -- removing exceptions constraints without a quadratic growth of -- instances. It uses some non-Haskell-98 type hackery, see the -- exception package by Joseph Iborra. Fortunately, you use this -- package in every case and let the user decide whether he wants Haskell -- 98 or non-standard way of handling exceptions. -- -- See also: https://wiki.haskell.org/Exception. 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 fromExitCode :: ExitCode -> Exceptional Int () toExitCode :: Exceptional Int () -> ExitCode -- | useful in connection with 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 -- | see mergeT merge :: Monoid e => Exceptional e (a -> b) -> Exceptional e a -> Exceptional e b infixl 4 `merge` alternative :: Exceptional e a -> Exceptional e a -> Exceptional e a infixl 3 `alternative` -- | 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) fromMaybeT :: Monad m => e -> MaybeT m a -> ExceptionalT e m a toMaybeT :: Monad m => ExceptionalT e m a -> MaybeT m a fromEitherT :: Monad m => m (Either e a) -> ExceptionalT e m a toEitherT :: Monad m => ExceptionalT e m a -> m (Either e a) fromExitCodeT :: Functor m => m ExitCode -> ExceptionalT Int m () toExitCodeT :: Functor m => ExceptionalT Int m () -> m ExitCode liftT :: Monad m => Exceptional e a -> ExceptionalT e m a switchT :: Monad m => (e -> m b) -> (a -> m b) -> ExceptionalT e m a -> m b -- | 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 -- | This combines two actions similar to Applicative's *. -- The result action fails if one of the input action fails, but both -- actions are executed. E.g. consider a compiler that emits all errors -- that can be detected independently, but eventually aborts if there is -- at least one error. -- -- The exception type e might be a list type, or an -- Endo type that implements a difflist. mergeT :: (Monoid e, Monad m) => ExceptionalT e m (a -> b) -> ExceptionalT e m a -> ExceptionalT e m b infixl 4 `mergeT` alternativeT :: Monad m => ExceptionalT e m a -> ExceptionalT e m a -> ExceptionalT e m a infixl 3 `alternativeT` instance (GHC.Classes.Eq a, GHC.Classes.Eq e) => GHC.Classes.Eq (Control.Monad.Exception.Synchronous.Exceptional e a) instance (GHC.Show.Show a, GHC.Show.Show e) => GHC.Show.Show (Control.Monad.Exception.Synchronous.Exceptional e a) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Exception.Synchronous.ExceptionalT e m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Monad.Exception.Synchronous.ExceptionalT e m) instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Exception.Synchronous.ExceptionalT e m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Exception.Synchronous.ExceptionalT e m) instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Exception.Synchronous.ExceptionalT e) instance (Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Control.Monad.Exception.Synchronous.Exceptional e a) instance GHC.Base.Functor (Control.Monad.Exception.Synchronous.Exceptional e) instance GHC.Base.Applicative (Control.Monad.Exception.Synchronous.Exceptional e) instance GHC.Base.Monad (Control.Monad.Exception.Synchronous.Exceptional e) instance Control.Monad.Fix.MonadFix (Control.Monad.Exception.Synchronous.Exceptional e) module Control.Monad.Exception.Asynchronous.Strict -- | Contains a value and a reason why the computation of the value of type -- a was terminated. Imagine a as a list type, and an -- according operation like the readFile operation. If the -- exception part is Nothing then the value could be constructed -- regularly. If the exception part is Just then the value could -- not be constructed completely. However you can read the result of type -- a lazily, even if an exception occurs while it is evaluated. -- If you evaluate the exception part, then the result value is certainly -- computed completely. -- -- However, we cannot provide general Monad functionality due to -- the very different ways of combining the results of type a. -- It is recommended to process the result value in an application -- specific way, and after consumption of the result, throw a synchronous -- exception using toSynchronous. -- -- Maybe in the future we provide a monad instance which considers -- subsequent actions as simultaneous processes on a lazy data structure. data Exceptional e a Exceptional :: Maybe e -> a -> Exceptional e a [exception] :: Exceptional e a -> Maybe e [result] :: Exceptional e a -> a -- | Create an exceptional value without exception. pure :: a -> Exceptional e a -- | Create an exceptional value with exception. broken :: e -> a -> Exceptional e a fromSynchronous :: a -> Exceptional e a -> Exceptional e a fromSynchronousNull :: Exceptional e () -> Exceptional e () fromSynchronousMonoid :: Monoid a => Exceptional e a -> Exceptional e a toSynchronous :: Exceptional e a -> Exceptional e a -- | I think in most cases we want throwMonoid, thus we can replace -- throw by throwMonoid. throw :: e -> Exceptional e () throwMonoid :: Monoid a => e -> Exceptional e a -- | You might use an exception of type Maybe e in -- manyMonoidT in order to stop the loop. After finishing the loop -- you will want to turn the Nothing exception into a success. -- This is achieved by this function. eatNothing :: Exceptional (Maybe e) a -> Exceptional e a -- | This is an example for application specific handling of result values. -- Assume you obtain two lazy lists say from readFile and you -- want to zip their contents. If one of the stream readers emits an -- exception, we quit with that exception. If both streams have throw an -- exception at the same file position, the exception of the first stream -- is propagated. zipWith :: (a -> b -> c) -> Exceptional e [a] -> Exceptional e [b] -> Exceptional e [c] -- | 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 is less strict than the Monoid method -- mappend instance. append :: Monoid a => Exceptional e a -> Exceptional e a -> Exceptional e a infixr 1 `append` continue :: Monoid a => Maybe e -> Exceptional e a -> Exceptional e a infixr 1 `continue` maybeAbort :: Exceptional e a -> Maybe e -> Exceptional e a infixr 1 `maybeAbort` -- | construct Exceptional constructor lazily 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 -- | I consider both actions to process the data simultaneously through -- lazy evaluation. If the second one fails too, it must have encountered -- an exception in the data that was successfully emitted by the first -- action, and thus the exception of the second action is probably -- earlier. -- -- We cannot check in general whether the two exception occur at the same -- time, e.g. the second one might occur since the first occured and left -- an invalid structure. In this case we should emit the first exception, -- not the second one. Because of this I expect that this function is not -- particularly useful. Otherwise it could be used as bind operation for -- a monad instance. -- | Deprecated: Check whether this function is really what you need. It -- generates an unreasonable exception when the second exception is -- caused by the first one. simultaneousBind :: Exceptional e a -> (a -> Exceptional e b) -> Exceptional e b infixr 1 `simultaneousBind` -- | Deprecated: Check whether this function is really what you need. It -- generates an unreasonable exception when the second exception is -- caused by the first one. simultaneousBindM :: Monad m => m (Exceptional e a) -> (a -> m (Exceptional e b)) -> m (Exceptional e b) infixr 1 `simultaneousBindM` -- | Is there a better name? sequenceF :: Functor f => Exceptional e (f a) -> f (Exceptional e a) -- | Foldable instance would allow to strip off the exception too -- easily. -- -- I like the methods of Traversable, but Traversable -- instance requires Foldable instance. traverse :: Applicative f => (a -> f b) -> Exceptional e a -> f (Exceptional e b) sequenceA :: Applicative f => Exceptional e (f a) -> f (Exceptional e a) mapM :: Monad m => (a -> m b) -> Exceptional e a -> m (Exceptional e b) sequence :: Monad m => Exceptional e (m a) -> m (Exceptional e a) -- | Consider a file format consisting of a header and a data body. The -- header can only be used if is read completely. Its parsing might stop -- with an synchronous exception. The data body can also be used if it is -- truncated by an exceptional event. This is expressed by an -- asynchronous exception. A loader for this file format can thus fail by -- a synchronous and an asynchronous exception. Surprisingly, both orders -- of nesting these two kinds of exceptional actions are equally -- expressive. This function converts to the form where the synchronous -- exception is the outer one. -- -- This is a specialisation of sequence and friends. swapToSynchronousAsynchronous :: Exceptional e0 (Exceptional e1 a) -> Exceptional e1 (Exceptional e0 a) swapToAsynchronousSynchronous :: Exceptional e1 (Exceptional e0 a) -> Exceptional e0 (Exceptional e1 a) -- | In contrast to synchronous exceptions, the asynchronous monad -- transformer is not quite a monad. You must use the Monoid -- interface or bindT instead. newtype ExceptionalT e m a ExceptionalT :: m (Exceptional e a) -> ExceptionalT e m a [runExceptionalT] :: ExceptionalT e m a -> m (Exceptional e a) fromSynchronousT :: Functor m => a -> ExceptionalT e m a -> ExceptionalT e m a fromSynchronousMonoidT :: (Functor m, Monoid a) => ExceptionalT e m a -> ExceptionalT e m 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 throwMonoidT :: (Monad m, Monoid a) => e -> ExceptionalT e m a eatNothingT :: Monad m => ExceptionalT (Maybe e) m a -> ExceptionalT e m a -- | The monadic bind operation. It cannot be made an instance of the Monad -- class method (>>=) since it requires a default return -- value in case the first action fails. We get this default value by the -- Monoid method mempty. bindT :: (Monad m, Monoid b) => ExceptionalT e m a -> (a -> ExceptionalT e m b) -> ExceptionalT e m b infixl 1 `bindT` -- | Repeat an action with synchronous exceptions until an exception -- occurs. Combine all atomic results using the bind function. -- It may be cons = (:) and empty = [] for b -- being a list type. The defer function may be id or -- unsafeInterleaveIO for lazy read operations. The exception is -- returned as asynchronous exception. -- | Deprecated: use manyMonoidT with appropriate Monad like LazyIO and -- result Monoid like Endo instead manySynchronousT :: Monad m => (m (Exceptional e b) -> m (Exceptional e b)) -> (a -> b -> b) -> b -> ExceptionalT e m a -> m (Exceptional e b) -- | We advise to use the Endo Monoid when you want to read a series of -- characters into a list. This means you use the difference lists -- technique in order to build the list, which is efficient. -- --
-- 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) infixr 1 `appendM` continueM :: (Monad m, Monoid a) => m (Maybe e) -> m (Exceptional e a) -> m (Exceptional e a) infixr 1 `continueM` instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Control.Monad.Exception.Asynchronous.Strict.Exceptional e a) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Exception.Asynchronous.Strict.ExceptionalT e m) instance (GHC.Base.Monad m, GHC.Base.Monoid a) => GHC.Base.Semigroup (Control.Monad.Exception.Asynchronous.Strict.ExceptionalT e m a) instance (GHC.Base.Monad m, GHC.Base.Monoid a) => GHC.Base.Monoid (Control.Monad.Exception.Asynchronous.Strict.ExceptionalT e m a) instance (Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Control.Monad.Exception.Asynchronous.Strict.Exceptional e a) instance GHC.Base.Monoid a => GHC.Base.Semigroup (Control.Monad.Exception.Asynchronous.Strict.Exceptional e a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Control.Monad.Exception.Asynchronous.Strict.Exceptional e a) instance GHC.Base.Functor (Control.Monad.Exception.Asynchronous.Strict.Exceptional e) module Control.Monad.Exception.Asynchronous.Lazy -- | Contains a value and a reason why the computation of the value of type -- a was terminated. Imagine a as a list type, and an -- according operation like the readFile operation. If the -- exception part is Nothing then the value could be constructed -- regularly. If the exception part is Just then the value could -- not be constructed completely. However you can read the result of type -- a lazily, even if an exception occurs while it is evaluated. -- If you evaluate the exception part, then the result value is certainly -- computed completely. -- -- However, we cannot provide general Monad functionality due to -- the very different ways of combining the results of type a. -- It is recommended to process the result value in an application -- specific way, and after consumption of the result, throw a synchronous -- exception using toSynchronous. -- -- Maybe in the future we provide a monad instance which considers -- subsequent actions as simultaneous processes on a lazy data structure. -- -- This variant has lazy combinators like fmap. This implies that -- some laws are not fulfilled, but in practice it saves you some calls -- to force. data Exceptional e a Exceptional :: Maybe e -> a -> Exceptional e a [exception] :: Exceptional e a -> Maybe e [result] :: Exceptional e a -> a -- | Create an exceptional value without exception. pure :: a -> Exceptional e a -- | Create an exceptional value with exception. broken :: e -> a -> Exceptional e a fromSynchronous :: a -> Exceptional e a -> Exceptional e a fromSynchronousNull :: Exceptional e () -> Exceptional e () fromSynchronousMonoid :: Monoid a => Exceptional e a -> Exceptional e a toSynchronous :: Exceptional e a -> Exceptional e a -- | I think in most cases we want throwMonoid, thus we can replace -- throw by throwMonoid. throw :: e -> Exceptional e () throwMonoid :: Monoid a => e -> Exceptional e a -- | You might use an exception of type Maybe e in -- manyMonoidT in order to stop the loop. After finishing the loop -- you will want to turn the Nothing exception into a success. -- This is achieved by this function. eatNothing :: Exceptional (Maybe e) a -> Exceptional e a -- | This is an example for application specific handling of result values. -- Assume you obtain two lazy lists say from readFile and you -- want to zip their contents. If one of the stream readers emits an -- exception, we quit with that exception. If both streams have throw an -- exception at the same file position, the exception of the first stream -- is propagated. zipWith :: (a -> b -> c) -> Exceptional e [a] -> Exceptional e [b] -> Exceptional e [c] -- | 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 is less strict than the Monoid method -- mappend instance. append :: Monoid a => Exceptional e a -> Exceptional e a -> Exceptional e a infixr 1 `append` continue :: Monoid a => Maybe e -> Exceptional e a -> Exceptional e a infixr 1 `continue` maybeAbort :: Exceptional e a -> Maybe e -> Exceptional e a infixr 1 `maybeAbort` -- | construct Exceptional constructor lazily 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 -- | I consider both actions to process the data simultaneously through -- lazy evaluation. If the second one fails too, it must have encountered -- an exception in the data that was successfully emitted by the first -- action, and thus the exception of the second action is probably -- earlier. -- -- We cannot check in general whether the two exception occur at the same -- time, e.g. the second one might occur since the first occured and left -- an invalid structure. In this case we should emit the first exception, -- not the second one. Because of this I expect that this function is not -- particularly useful. Otherwise it could be used as bind operation for -- a monad instance. -- | Deprecated: Check whether this function is really what you need. It -- generates an unreasonable exception when the second exception is -- caused by the first one. simultaneousBind :: Exceptional e a -> (a -> Exceptional e b) -> Exceptional e b infixr 1 `simultaneousBind` -- | Deprecated: Check whether this function is really what you need. It -- generates an unreasonable exception when the second exception is -- caused by the first one. simultaneousBindM :: Monad m => m (Exceptional e a) -> (a -> m (Exceptional e b)) -> m (Exceptional e b) infixr 1 `simultaneousBindM` -- | Is there a better name? sequenceF :: Functor f => Exceptional e (f a) -> f (Exceptional e a) -- | Foldable instance would allow to strip off the exception too -- easily. -- -- I like the methods of Traversable, but Traversable -- instance requires Foldable instance. traverse :: Applicative f => (a -> f b) -> Exceptional e a -> f (Exceptional e b) sequenceA :: Applicative f => Exceptional e (f a) -> f (Exceptional e a) mapM :: Monad m => (a -> m b) -> Exceptional e a -> m (Exceptional e b) sequence :: Monad m => Exceptional e (m a) -> m (Exceptional e a) -- | Consider a file format consisting of a header and a data body. The -- header can only be used if is read completely. Its parsing might stop -- with an synchronous exception. The data body can also be used if it is -- truncated by an exceptional event. This is expressed by an -- asynchronous exception. A loader for this file format can thus fail by -- a synchronous and an asynchronous exception. Surprisingly, both orders -- of nesting these two kinds of exceptional actions are equally -- expressive. This function converts to the form where the synchronous -- exception is the outer one. -- -- This is a specialisation of sequence and friends. swapToSynchronousAsynchronous :: Exceptional e0 (Exceptional e1 a) -> Exceptional e1 (Exceptional e0 a) swapToAsynchronousSynchronous :: Exceptional e1 (Exceptional e0 a) -> Exceptional e0 (Exceptional e1 a) -- | In contrast to synchronous exceptions, the asynchronous monad -- transformer is not quite a monad. You must use the Monoid -- interface or bindT instead. newtype ExceptionalT e m a ExceptionalT :: m (Exceptional e a) -> ExceptionalT e m a [runExceptionalT] :: ExceptionalT e m a -> m (Exceptional e a) fromSynchronousT :: Functor m => a -> ExceptionalT e m a -> ExceptionalT e m a fromSynchronousMonoidT :: (Functor m, Monoid a) => ExceptionalT e m a -> ExceptionalT e m 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 throwMonoidT :: (Monad m, Monoid a) => e -> ExceptionalT e m a eatNothingT :: Monad m => ExceptionalT (Maybe e) m a -> ExceptionalT e m a -- | The monadic bind operation. It cannot be made an instance of the Monad -- class method (>>=) since it requires a default return -- value in case the first action fails. We get this default value by the -- Monoid method mempty. bindT :: (Monad m, Monoid b) => ExceptionalT e m a -> (a -> ExceptionalT e m b) -> ExceptionalT e m b infixl 1 `bindT` -- | Repeat an action with synchronous exceptions until an exception -- occurs. Combine all atomic results using the bind function. -- It may be cons = (:) and empty = [] for b -- being a list type. The defer function may be id or -- unsafeInterleaveIO for lazy read operations. The exception is -- returned as asynchronous exception. -- | Deprecated: use manyMonoidT with appropriate Monad like LazyIO and -- result Monoid like Endo instead manySynchronousT :: Monad m => (m (Exceptional e b) -> m (Exceptional e b)) -> (a -> b -> b) -> b -> ExceptionalT e m a -> m (Exceptional e b) -- | We advise to use the Endo Monoid when you want to read a series of -- characters into a list. This means you use the difference lists -- technique in order to build the list, which is efficient. -- --
-- 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) infixr 1 `appendM` continueM :: (Monad m, Monoid a) => m (Maybe e) -> m (Exceptional e a) -> m (Exceptional e a) infixr 1 `continueM` instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Control.Monad.Exception.Asynchronous.Lazy.Exceptional e a) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Exception.Asynchronous.Lazy.ExceptionalT e m) instance (GHC.Base.Monad m, GHC.Base.Monoid a) => GHC.Base.Semigroup (Control.Monad.Exception.Asynchronous.Lazy.ExceptionalT e m a) instance (GHC.Base.Monad m, GHC.Base.Monoid a) => GHC.Base.Monoid (Control.Monad.Exception.Asynchronous.Lazy.ExceptionalT e m a) instance (Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Control.Monad.Exception.Asynchronous.Lazy.Exceptional e a) instance GHC.Base.Monoid a => GHC.Base.Semigroup (Control.Monad.Exception.Asynchronous.Lazy.Exceptional e a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Control.Monad.Exception.Asynchronous.Lazy.Exceptional e a) instance GHC.Base.Functor (Control.Monad.Exception.Asynchronous.Lazy.Exceptional e) -- | Asynchronous exceptions can occur during the construction of a lazy -- data structure. They are represented by a lazy data structure itself. -- -- This module re-exports the type with lazy combinators. -- -- TODO: -- --