contstuff 0.2.2 → 0.3.0
raw patch · 2 files changed
+187/−17 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.ContStuff: EitherT :: ((a -> m r) -> (e -> m r) -> m r) -> EitherT r e m a
+ Control.ContStuff: bracket :: (HasExceptions m, Monad m) => m res -> (res -> m b) -> (res -> m a) -> m a
+ Control.ContStuff: bracket_ :: (HasExceptions m, Monad m) => m a -> m b -> m c -> m c
+ Control.ContStuff: catch :: (HasExceptions m, Monad m) => m a -> (Exception m -> m a) -> m a
+ Control.ContStuff: class HasExceptions m where { type family Exception m; }
+ Control.ContStuff: evalEitherT :: (Applicative m) => EitherT (Either e a) e m a -> m (Either e a)
+ Control.ContStuff: finally :: (HasExceptions m, Monad m) => m a -> m b -> m a
+ Control.ContStuff: getEitherT :: EitherT r e m a -> (a -> m r) -> (e -> m r) -> m r
+ Control.ContStuff: handle :: (HasExceptions m, Monad m) => (Exception m -> m a) -> m a -> m a
+ Control.ContStuff: instance (Alternative m) => Alternative (EitherT r e m)
+ Control.ContStuff: instance (Alternative m) => Writable (EitherT r e m) r
+ Control.ContStuff: instance (Applicative m) => Abortable (EitherT r e m)
+ Control.ContStuff: instance (Functor m, Monoid w) => Writable (EitherT (r, w) e m) w
+ Control.ContStuff: instance Applicative (EitherT r e m)
+ Control.ContStuff: instance CallCC (EitherT r e m)
+ Control.ContStuff: instance Functor (EitherT r e m)
+ Control.ContStuff: instance HasExceptions (Either e)
+ Control.ContStuff: instance HasExceptions (EitherT r e m)
+ Control.ContStuff: instance HasExceptions IO
+ Control.ContStuff: instance HasExceptions Maybe
+ Control.ContStuff: instance Monad (EitherT r e m)
+ Control.ContStuff: instance Runnable (EitherT r e) r m a
+ Control.ContStuff: instance Transformer (EitherT r e)
+ Control.ContStuff: newtype EitherT r e m a
+ Control.ContStuff: raise :: (HasExceptions m) => Exception m -> m a
+ Control.ContStuff: runEitherT :: (a -> m r) -> (e -> m r) -> EitherT r e m a -> m r
+ Control.ContStuff: try :: (HasExceptions m) => m a -> m (Either (Exception m) a)
- Control.ContStuff: goto :: (Applicative m) => Label m a -> a -> m b
+ Control.ContStuff: goto :: Label m a -> a -> m ()
Files
- Control/ContStuff.hs +186/−16
- contstuff.cabal +1/−1
Control/ContStuff.hs view
@@ -14,33 +14,46 @@ TypeFamilies #-} module Control.ContStuff- ( -- * The identity monad- Id(..),-- -- * Monad transformers+ ( -- * Monad transformers -- ** Identity transformer IdT(..),- -- ** Basic CPS monads- Cont, runCont, evalCont, modifyCont,+ -- ** ContT ContT(..), runContT, evalContT, modifyContT,- -- ** Advanced CPS monads- -- *** Choice/nondeterminism+ -- ** Choice/nondeterminism ChoiceT(..), runChoiceT, findFirst, findAll, listChoiceT, listA,- -- *** State- State, runState, evalState, execState,+ -- ** Exceptions+ EitherT(..), runEitherT, evalEitherT,+ -- ** State StateT(..), runStateT, evalStateT, execStateT, -- ** Writer monads- OldWriter, runOldWriter, evalOldWriter, execOldWriter,- OldWriterT, runOldWriterT, evalOldWriterT, execOldWriterT, WriterT, runWriterT,+ OldWriterT, runOldWriterT, evalOldWriterT, execOldWriterT, + -- * Monads+ -- ** Identity monad+ Id(..),+ -- ** Cont+ Cont, runCont, evalCont, modifyCont,+ -- ** State+ State, runState, evalState, execState,+ -- ** Writer+ OldWriter, runOldWriter, evalOldWriter, execOldWriter,+ -- * Effect classes+ -- ** Abortion Abortable(..),+ -- ** Call with current continuation CallCC(..), Label, labelCC, goto,+ -- ** Exceptions+ HasExceptions(..), catch, handle, finally, bracket, bracket_,+ -- ** Lifting+ Transformer(..), LiftBase(..), io,+ -- ** Running Runnable(..),+ -- ** State Stateful(..), getField, modify, modifyField, modifyFieldLazy, modifyLazy,- Transformer(..),+ -- ** Logging support (writers) Writable(..), -- * Module reexports@@ -49,12 +62,14 @@ ) where +import qualified Control.Exception as E import Control.Applicative import Control.Arrow import Control.Monad import Control.Monad.Fix import Control.Monad.ST import Data.Monoid+import Prelude hiding (catch) -- ================== --@@ -255,6 +270,76 @@ modifyCont = modifyContT +-------------+-- EitherT --+-------------++-- | Monad transformer for CPS computations with an additional exception+-- continuation.++newtype EitherT r e m a =+ EitherT { getEitherT :: (a -> m r) -> (e -> m r) -> m r }++instance Applicative m => Abortable (EitherT r e m) where+ type Result (EitherT r e m) = r+ abort x = EitherT $ \_ _ -> pure x++instance Applicative (EitherT r e m) where+ pure x = EitherT $ \k _ -> k x+ EitherT cf <*> EitherT cx =+ EitherT $ \k expk -> cf (\f -> cx (\x -> k (f x)) expk) expk++instance Alternative m => Alternative (EitherT r e m) where+ empty = EitherT $ \_ _ -> empty+ EitherT c <|> EitherT d =+ EitherT $ \k expk -> c k expk <|> d k expk++instance CallCC (EitherT r e m) where+ callCC f =+ EitherT $ \k expk ->+ getEitherT (f (\x -> EitherT $ \_ _ -> k x)) k expk++instance HasExceptions (EitherT r e m) where+ type Exception (EitherT r e m) = e+ raise exp = EitherT $ \_ expk -> expk exp+ try (EitherT c) = EitherT $ \k _ -> c (k . Right) (k . Left)++instance Functor (EitherT r e m) where+ fmap f (EitherT c) =+ EitherT $ \k expk -> c (k . f) expk++instance Monad (EitherT r e m) where+ return x = EitherT $ \k _ -> k x+ EitherT c >>= f =+ EitherT $ \k expk ->+ c (\x -> getEitherT (f x) k expk) expk++instance Runnable (EitherT r e) r m a where+ type Argument (EitherT r e) r m a = (a -> m r, e -> m r)+ runT (k, expk) (EitherT c) = c k expk++instance Transformer (EitherT r e) where+ lift c = EitherT $ \k _ -> c >>= k++instance Alternative m => Writable (EitherT r e m) r where+ tell x = EitherT $ \k _ -> pure x <|> k ()++instance (Functor m, Monoid w) => Writable (EitherT (r, w) e m) w where+ tell x = EitherT $ \k _ -> fmap (second (`mappend` x)) (k ())+++-- | Run an 'EitherT' transformer.++runEitherT :: (a -> m r) -> (e -> m r) -> EitherT r e m a -> m r+runEitherT k expk (EitherT c) = c k expk+++-- | Run an 'EitherT' transformer returning an 'Either' result.++evalEitherT :: Applicative m => EitherT (Either e a) e m a -> m (Either e a)+evalEitherT (EitherT c) = c (pure . Right) (pure . Left)++ --------- -- IdT -- ---------@@ -346,6 +431,8 @@ -- StateT -- ------------ +-- | Monad transformer for stateful computations.+ newtype StateT r s m a = StateT { getStateT :: s -> (s -> a -> m r) -> m r } @@ -364,7 +451,9 @@ StateT $ \s0 k -> cf s0 (\s1 f -> cx s1 (\s2 x -> k s2 (f x))) instance CallCC (StateT r s m) where- callCC f = StateT $ \s0 k -> getStateT (f (\x -> StateT $ \s1 _ -> k s1 x)) s0 k+ callCC f =+ StateT $ \s0 k ->+ getStateT (f (\x -> StateT $ \s1 _ -> k s1 x)) s0 k instance Functor (StateT r s m) where fmap f (StateT c) =@@ -481,8 +570,89 @@ -- | Jump to a label. -goto :: Applicative m => Label m a -> a -> m b-goto lk@(Label k) x = k x lk *> pure undefined+goto :: Label m a -> a -> m ()+goto lk@(Label k) x = k x lk+++-- | Monads with exception support.++class HasExceptions m where+ -- | The exception type.+ type Exception m++ -- | Raise an exception.+ raise :: Exception m -> m a++ -- | Run computation catching exceptions.+ try :: m a -> m (Either (Exception m) a)++instance HasExceptions (Either e) where+ type Exception (Either e) = e+ raise = Left+ try = Right++instance HasExceptions Maybe where+ type Exception Maybe = ()+ raise = const Nothing+ try = Just . maybe (Left ()) Right++instance HasExceptions IO where+ type Exception IO = E.SomeException+ raise = E.throwIO+ try = E.try+++-- | Catch exceptions using an exception handler.++catch :: (HasExceptions m, Monad m) => m a -> (Exception m -> m a) -> m a+catch c h = try c >>= either h return+++-- | Catch exceptions using an exception handler (flip 'catch').++handle :: (HasExceptions m, Monad m) => (Exception m -> m a) -> m a -> m a+handle h c = try c >>= either h return+++-- | Run a final computation regardless of whether an exception was+-- raised.++finally :: (HasExceptions m, Monad m) => m a -> m b -> m a+finally c d = try c >>= either (\exp -> d >> raise exp) (\x -> d >> return x)+++-- | Get a resource, run a computation, then release the resource, even+-- if an exception is raised:+--+-- > bracket acquire release use+--+-- Please note that this function behaves slightly different from the+-- usual 'E.bracket'. If both the user and the releaser throw an+-- exception, the user exception is significant.++bracket :: (HasExceptions m, Monad m) => m res -> (res -> m b) -> (res -> m a) -> m a+bracket acquire release use = do+ resource <- acquire+ result <- try (use resource)+ try (release resource)+ either raise return result+++-- | Initialize, then run, then clean up safely, even if an exception is+-- raised:+--+-- > bracket_ init cleanup run+--+-- Please note that this function behaves slightly different from the+-- usual 'E.bracket_'. If both the user and the releaser throw an+-- exception, the user exception is significant.++bracket_ :: (HasExceptions m, Monad m) => m a -> m b -> m c -> m c+bracket_ init cleanup run = do+ init+ result <- try run+ try cleanup+ either raise return result -- | Monads, which support lifting base monad computations.
contstuff.cabal view
@@ -1,5 +1,5 @@ Name: contstuff-Version: 0.2.2+Version: 0.3.0 Category: Control, Monads Synopsis: Easy to use CPS-based monads Maintainer: Ertugrul Söylemez <es@ertes.de>