transformers 0.2.2.1 → 0.3.0.0
raw patch · 20 files changed
+553/−136 lines, 20 files
Files
- Control/Applicative/Backwards.hs +49/−0
- Control/Applicative/Lift.hs +68/−0
- Control/Monad/Trans/Class.hs +7/−7
- Control/Monad/Trans/Cont.hs +16/−0
- Control/Monad/Trans/Error.hs +20/−6
- Control/Monad/Trans/Identity.hs +14/−2
- Control/Monad/Trans/List.hs +9/−1
- Control/Monad/Trans/Maybe.hs +16/−0
- Control/Monad/Trans/RWS/Lazy.hs +79/−19
- Control/Monad/Trans/RWS/Strict.hs +79/−19
- Control/Monad/Trans/Reader.hs +19/−9
- Control/Monad/Trans/State.hs +1/−1
- Control/Monad/Trans/State/Lazy.hs +17/−18
- Control/Monad/Trans/State/Strict.hs +17/−18
- Control/Monad/Trans/Writer/Lazy.hs +21/−12
- Control/Monad/Trans/Writer/Strict.hs +19/−10
- Data/Functor/Identity.hs +1/−1
- Data/Functor/Product.hs +19/−0
- Data/Functor/Reverse.hs +54/−0
- transformers.cabal +28/−13
+ Control/Applicative/Backwards.hs view
@@ -0,0 +1,49 @@+-- |+-- Module : Control.Applicative.Backwards+-- Copyright : (c) Russell O'Connor 2009+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- Making functors with an 'Applicative' instance that performs actions+-- in the reverse order.++module Control.Applicative.Backwards where++import Prelude hiding (foldr, foldr1, foldl, foldl1)+import Control.Applicative+import Data.Foldable+import Data.Traversable++-- | The same functor, but with an 'Applicative' instance that performs+-- actions in the reverse order.+newtype Backwards f a = Backwards { forwards :: f a }++-- | Derived instance.+instance (Functor f) => Functor (Backwards f) where+ fmap f (Backwards a) = Backwards (fmap f a)++-- | Apply @f@-actions in the reverse order.+instance (Applicative f) => Applicative (Backwards f) where+ pure a = Backwards (pure a)+ Backwards f <*> Backwards a = Backwards (a <**> f)++-- | Try alternatives in the same order as @f@.+instance (Alternative f) => Alternative (Backwards f) where+ empty = Backwards empty+ Backwards x <|> Backwards y = Backwards (x <|> y)++-- | Derived instance.+instance (Foldable f) => Foldable (Backwards f) where+ foldMap f (Backwards t) = foldMap f t+ foldr f z (Backwards t) = foldr f z t+ foldl f z (Backwards t) = foldl f z t+ foldr1 f (Backwards t) = foldl1 f t+ foldl1 f (Backwards t) = foldr1 f t++-- | Derived instance.+instance (Traversable f) => Traversable (Backwards f) where+ traverse f (Backwards t) = fmap Backwards (traverse f t)+ sequenceA (Backwards t) = fmap Backwards (sequenceA t)
+ Control/Applicative/Lift.hs view
@@ -0,0 +1,68 @@+-- |+-- Module : Control.Applicative.Lift+-- Copyright : (c) Ross Paterson 2010+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : ross@soi.city.ac.uk+-- Stability : experimental+-- Portability : portable+--+-- Adding a new kind of pure computation to an applicative functor.++module Control.Applicative.Lift (+ Lift(..), unLift,+ -- * Collecting errors+ Errors, failure+ ) where++import Control.Applicative+import Data.Foldable (Foldable(foldMap))+import Data.Functor.Constant+import Data.Monoid (Monoid(mappend))+import Data.Traversable (Traversable(traverse))++-- | Applicative functor formed by adding pure computations to a given+-- applicative functor.+data Lift f a = Pure a | Other (f a)++instance (Functor f) => Functor (Lift f) where+ fmap f (Pure x) = Pure (f x)+ fmap f (Other y) = Other (fmap f y)++instance (Foldable f) => Foldable (Lift f) where+ foldMap f (Pure x) = f x+ foldMap f (Other y) = foldMap f y++instance (Traversable f) => Traversable (Lift f) where+ traverse f (Pure x) = Pure <$> f x+ traverse f (Other y) = Other <$> traverse f y++-- | A combination is 'Pure' only if both parts are.+instance (Applicative f) => Applicative (Lift f) where+ pure = Pure+ Pure f <*> Pure x = Pure (f x)+ Pure f <*> Other y = Other (f <$> y)+ Other f <*> Pure x = Other (($ x) <$> f)+ Other f <*> Other y = Other (f <*> y)++-- | A combination is 'Pure' only either part is.+instance Alternative f => Alternative (Lift f) where+ empty = Other empty+ Pure x <|> _ = Pure x+ Other _ <|> Pure y = Pure y+ Other x <|> Other y = Other (x <|> y)++-- | Projection to the other functor.+unLift :: Applicative f => Lift f a -> f a+unLift (Pure x) = pure x+unLift (Other e) = e++-- | An applicative functor that collects a monoid (e.g. lists) of errors.+-- A sequence of computations fails if any of its components do, but+-- unlike monads made with 'ErrorT' from "Control.Monad.Trans.Error",+-- these computations continue after an error, collecting all the errors.+type Errors e = Lift (Constant e)++-- | Report an error.+failure :: Monoid e => e -> Errors e a+failure e = Other (Constant e)
Control/Monad/Trans/Class.hs view
@@ -11,7 +11,7 @@ -- -- Classes for monad transformers. ----- A monad transformer makes new monad out of an existing monad, such+-- A monad transformer makes a new monad out of an existing monad, such -- that computations of the old monad may be embedded in the new one. -- To construct a monad with a desired set of features, one typically -- starts with a base monad, such as @Identity@, @[]@ or 'IO', and@@ -77,8 +77,8 @@ In this example we use the operations @get@ and @put@ from "Control.Monad.Trans.State", which are defined only for monads that are applications of @StateT@. Alternatively one could use monad classes-from other packages, which contain methods @get@ and @put@ with types-generalized over all suitable monads.+from the @mtl@ package or similar, which contain methods @get@ and @put@+with types generalized over all suitable monads. -} {- $example2@@ -109,10 +109,10 @@ In this case, we were able to do this with 'lift', but operations with more complex types require special lifting functions, which are provided-by monad transformers for which they can be implemented. If you use-one of packages of monad classes, this lifting is handled automatically-by the instances of the classes, and you need only use the generalized-methods @get@ and @put@.+by monad transformers for which they can be implemented. If you use the+monad classes of the @mtl@ package or similar, this lifting is handled+automatically by the instances of the classes, and you need only use+the generalized methods @get@ and @put@. We can also define a primitive using the Writer:
Control/Monad/Trans/Cont.hs view
@@ -60,9 +60,17 @@ -> r runCont m k = runIdentity (runContT m (Identity . k)) +-- | Apply a function to transform the result of a continuation-passing+-- computation.+--+-- * @'runCont' ('mapCont' f m) = f . 'runCont' m@ mapCont :: (r -> r) -> Cont r a -> Cont r a mapCont f = mapContT (Identity . f . runIdentity) +-- | Apply a function to transform the continuation passed to a CPS+-- computation.+--+-- * @'runCont' ('withCont' f m) = 'runCont' m . f@ withCont :: ((b -> r) -> (a -> r)) -> Cont r a -> Cont r b withCont f = withContT ((Identity .) . f . (runIdentity .)) @@ -72,9 +80,17 @@ -} newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r } +-- | Apply a function to transform the result of a continuation-passing+-- computation.+--+-- * @'runContT' ('mapContT' f m) = f . 'runContT' m@ mapContT :: (m r -> m r) -> ContT r m a -> ContT r m a mapContT f m = ContT $ f . runContT m +-- | Apply a function to transform the continuation passed to a CPS+-- computation.+--+-- * @'runContT' ('withContT' f m) = 'runContT' m . f@ withContT :: ((b -> m r) -> (a -> m r)) -> ContT r m a -> ContT r m b withContT f m = ContT $ runContT m . f
Control/Monad/Trans/Error.hs view
@@ -47,9 +47,10 @@ import Control.Exception (IOException) import Control.Monad import Control.Monad.Fix-#if !(MIN_VERSION_base(4,6,0))-import Control.Monad.Instances () -- deprecated from base-4.6-#endif+import Control.Monad.Instances ()+import Data.Foldable (Foldable(foldMap))+import Data.Monoid (mempty)+import Data.Traversable (Traversable(traverse)) import System.IO.Error instance MonadPlus IO where@@ -93,7 +94,7 @@ -- --------------------------------------------------------------------------- -- Our parameterizable error monad -#if !(MIN_VERSION_base(4,2,1))+#if !(MIN_VERSION_base(4,3,0)) -- These instances are in base-4.3 @@ -141,7 +142,7 @@ -- | Map the unwrapped computation using the given function. ----- * @'runErrorT' ('mapErrorT' f m) = f ('runErrorT' m@)+-- * @'runErrorT' ('mapErrorT' f m) = f ('runErrorT' m)@ mapErrorT :: (m (Either e a) -> n (Either e' b)) -> ErrorT e m a -> ErrorT e' n b@@ -150,6 +151,13 @@ instance (Functor m) => Functor (ErrorT e m) where fmap f = ErrorT . fmap (fmap f) . runErrorT +instance (Foldable f) => Foldable (ErrorT e f) where+ foldMap f (ErrorT a) = foldMap (either (const mempty) f) a++instance (Traversable f) => Traversable (ErrorT e f) where+ traverse f (ErrorT a) =+ ErrorT <$> traverse (either (pure . Left) (fmap Right . f)) a+ instance (Functor m, Monad m) => Applicative (ErrorT e m) where pure a = ErrorT $ return (Right a) f <*> v = ErrorT $ do@@ -198,11 +206,17 @@ -- | Signal an error value @e@. ----- * @'runErrorT' ('throwErrorT' e) = 'return' ('Left' e)@+-- * @'runErrorT' ('throwError' e) = 'return' ('Left' e)@+--+-- * @'throwError' e >>= m = 'throwError' e@ throwError :: (Monad m, Error e) => e -> ErrorT e m a throwError l = ErrorT $ return (Left l) -- | Handle an error.+--+-- * @'catchError' h ('lift' m) = 'lift' m@+--+-- * @'catchError' h ('throwError' e) = h e@ catchError :: (Monad m, Error e) => ErrorT e m a -- ^ the inner computation -> (e -> ErrorT e m a) -- ^ a handler for errors in the inner
Control/Monad/Trans/Identity.hs view
@@ -24,8 +24,11 @@ import Control.Applicative import Control.Monad (MonadPlus(mzero, mplus))+import Control.Monad.Fix (MonadFix(mfix)) import Control.Monad.IO.Class (MonadIO(liftIO)) import Control.Monad.Trans.Class (MonadTrans(lift))+import Data.Foldable (Foldable(foldMap))+import Data.Traversable (Traversable(traverse)) -- | The trivial monad transformer, which maps a monad to an equivalent monad. newtype IdentityT m a = IdentityT { runIdentityT :: m a }@@ -33,10 +36,16 @@ instance (Functor m) => Functor (IdentityT m) where fmap f = mapIdentityT (fmap f) +instance (Foldable f) => Foldable (IdentityT f) where+ foldMap f (IdentityT a) = foldMap f a++instance (Traversable f) => Traversable (IdentityT f) where+ traverse f (IdentityT a) = IdentityT <$> traverse f a+ instance (Applicative m) => Applicative (IdentityT m) where pure x = IdentityT (pure x) (<*>) = lift2IdentityT (<*>)- + instance (Alternative m) => Alternative (IdentityT m) where empty = IdentityT empty (<|>) = lift2IdentityT (<|>)@@ -45,10 +54,13 @@ return = IdentityT . return m >>= k = IdentityT $ runIdentityT . k =<< runIdentityT m fail msg = IdentityT $ fail msg- + instance (MonadPlus m) => MonadPlus (IdentityT m) where mzero = IdentityT mzero mplus = lift2IdentityT mplus++instance (MonadFix m) => MonadFix (IdentityT m) where+ mfix f = IdentityT (mfix (runIdentityT . f)) instance (MonadIO m) => MonadIO (IdentityT m) where liftIO = IdentityT . liftIO
Control/Monad/Trans/List.hs view
@@ -27,6 +27,8 @@ import Control.Applicative import Control.Monad+import Data.Foldable (Foldable(foldMap))+import Data.Traversable (Traversable(traverse)) -- | Parameterizable list monad, with an inner monad. --@@ -35,12 +37,18 @@ -- | Map between 'ListT' computations. ----- * @'runListT' ('mapListT' f m) = f ('runListT' m@)+-- * @'runListT' ('mapListT' f m) = f ('runListT' m)@ mapListT :: (m [a] -> n [b]) -> ListT m a -> ListT n b mapListT f m = ListT $ f (runListT m) instance (Functor m) => Functor (ListT m) where fmap f = mapListT $ fmap $ map f++instance Foldable f => Foldable (ListT f) where+ foldMap f (ListT a) = foldMap (foldMap f) a++instance Traversable f => Traversable (ListT f) where+ traverse f (ListT a) = ListT <$> traverse (traverse f) a instance (Applicative m) => Applicative (ListT m) where pure a = ListT $ pure [a]
Control/Monad/Trans/Maybe.hs view
@@ -34,6 +34,10 @@ import Control.Applicative import Control.Monad (MonadPlus(mzero, mplus), liftM, ap)+import Control.Monad.Fix (MonadFix(mfix))+import Data.Foldable (Foldable(foldMap))+import Data.Maybe (fromMaybe)+import Data.Traversable (Traversable(traverse)) -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the 'Maybe' monad.@@ -45,12 +49,20 @@ newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } -- | Transform the computation inside a @MaybeT@.+--+-- * @'runMaybeT' ('mapMaybeT' f m) = f ('runMaybeT' m)@ mapMaybeT :: (m (Maybe a) -> n (Maybe b)) -> MaybeT m a -> MaybeT n b mapMaybeT f = MaybeT . f . runMaybeT instance (Functor m) => Functor (MaybeT m) where fmap f = mapMaybeT (fmap (fmap f)) +instance (Foldable f) => Foldable (MaybeT f) where+ foldMap f (MaybeT a) = foldMap (foldMap f) a++instance (Traversable f) => Traversable (MaybeT f) where+ traverse f (MaybeT a) = MaybeT <$> traverse (traverse f) a+ instance (Functor m, Monad m) => Applicative (MaybeT m) where pure = return (<*>) = ap@@ -75,6 +87,10 @@ case v of Nothing -> runMaybeT y Just _ -> return v++instance (MonadFix m) => MonadFix (MaybeT m) where+ mfix f = MaybeT (mfix (runMaybeT . f . unJust))+ where unJust = fromMaybe (error "mfix MaybeT: Nothing") instance MonadTrans MaybeT where lift = MaybeT . liftM Just
Control/Monad/Trans/RWS/Lazy.hs view
@@ -30,16 +30,19 @@ mapRWST, withRWST, -- * Reader operations+ reader, ask, local, asks, -- * Writer operations+ writer, tell, listen, listens, pass, censor, -- * State operations+ state, get, put, modify,@@ -73,19 +76,37 @@ runRWS :: RWS r w s a -> r -> s -> (a, s, w) runRWS m r s = runIdentity (runRWST m r s) -evalRWS :: RWS r w s a -> r -> s -> (a, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final value and output, discarding the final state.+evalRWS :: RWS r w s a -- ^RWS computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> (a, w) -- ^final value and output evalRWS m r s = let (a, _, w) = runRWS m r s in (a, w) -execRWS :: RWS r w s a -> r -> s -> (s, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final state and output, discarding the final value.+execRWS :: RWS r w s a -- ^RWS computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> (s, w) -- ^final state and output execRWS m r s = let (_, s', w) = runRWS m r s in (s', w) +-- | Map the return value, final state and output of a computation using+-- the given function.+--+-- * @'runRWS' ('mapRWS' f m) r s = f ('runRWS' m r s)@ mapRWS :: ((a, s, w) -> (b, s, w')) -> RWS r w s a -> RWS r w' s b mapRWS f = mapRWST (Identity . f . runIdentity) +-- | @'withRWS' f m@ executes action @m@ with an initial environment+-- and state modified by applying @f@.+--+-- * @'runRWS' ('withRWS' f m) r s = 'uncurry' ('runRWS' m) (f r s)@ withRWS :: (r' -> s -> (r, s)) -> RWS r w s a -> RWS r' w s a withRWS = withRWST @@ -95,19 +116,38 @@ -- to an inner monad @m@. newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) } -evalRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (a, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final value and output, discarding the final state.+evalRWST :: (Monad m)+ => RWST r w s m a -- ^computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> m (a, w) -- ^computation yielding final value and output evalRWST m r s = do ~(a, _, w) <- runRWST m r s return (a, w) -execRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (s, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final state and output, discarding the final value.+execRWST :: (Monad m)+ => RWST r w s m a -- ^computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> m (s, w) -- ^computation yielding final state and output execRWST m r s = do ~(_, s', w) <- runRWST m r s return (s', w) +-- | Map the inner computation using the given function.+--+-- * @'runRWST' ('mapRWST' f m) r s = f ('runRWST' m r s)@ mapRWST :: (m (a, s, w) -> n (b, s, w')) -> RWST r w s m a -> RWST r w' s n b mapRWST f m = RWST $ \r s -> f (runRWST m r s) +-- | @'withRWST' f m@ executes action @m@ with an initial environment+-- and state modified by applying @f@.+--+-- * @'runRWST' ('withRWST' f m) r s = 'uncurry' ('runRWST' m) (f r s)@ withRWST :: (r' -> s -> (r, s)) -> RWST r w s m a -> RWST r' w s m a withRWST f m = RWST $ \r s -> uncurry (runRWST m) (f r s) @@ -149,29 +189,41 @@ -- --------------------------------------------------------------------------- -- Reader operations +-- | Constructor for computations in the reader monad (equivalent to 'asks').+reader :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a+reader = asks+ -- | Fetch the value of the environment. ask :: (Monoid w, Monad m) => RWST r w s m r ask = RWST $ \r s -> return (r, s, mempty) -- | Execute a computation in a modified environment+--+-- * @'runRWST' ('local' f m) r s = 'runRWST' m (f r) s@ local :: (Monoid w, Monad m) => (r -> r) -> RWST r w s m a -> RWST r w s m a local f m = RWST $ \r s -> runRWST m (f r) s -- | Retrieve a function of the current environment.+--+-- * @'asks' f = 'liftM' f 'ask'@ asks :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a-asks f = do- r <- ask- return (f r)+asks f = RWST $ \r s -> return (f r, s, mempty) -- --------------------------------------------------------------------------- -- Writer operations +-- | Construct a writer computation from a (result, output) pair.+writer :: Monad m => (a, w) -> RWST r w s m a+writer (a, w) = RWST $ \_ s -> return (a, s, w)+ -- | @'tell' w@ is an action that produces the output @w@. tell :: (Monoid w, Monad m) => w -> RWST r w s m () tell w = RWST $ \_ s -> return ((),s,w) -- | @'listen' m@ is an action that executes the action @m@ and adds its -- output to the value of the computation.+--+-- * @'runRWST' ('listen' m) r s = 'liftM' (\\(a, w) -> ((a, w), w)) ('runRWST' m r s)@ listen :: (Monoid w, Monad m) => RWST r w s m a -> RWST r w s m (a, w) listen m = RWST $ \r s -> do ~(a, s', w) <- runRWST m r s@@ -181,14 +233,18 @@ -- the result of applying @f@ to the output to the value of the computation. -- -- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@+--+-- * @'runRWST' ('listens' f m) r s = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runRWST' m r s)@ listens :: (Monoid w, Monad m) => (w -> b) -> RWST r w s m a -> RWST r w s m (a, b)-listens f m = do- ~(a, w) <- listen m- return (a, f w)+listens f m = RWST $ \r s -> do+ ~(a, s', w) <- runRWST m r s+ return ((a, f w), s', w) -- | @'pass' m@ is an action that executes the action @m@, which returns -- a value and a function, and returns the value, applying the function -- to the output.+--+-- * @'runRWST' ('pass' m) r s = 'liftM' (\\((a, f), w) -> (a, f w)) ('runRWST' m r s)@ pass :: (Monoid w, Monad m) => RWST r w s m (a, w -> w) -> RWST r w s m a pass m = RWST $ \r s -> do ~((a, f), s', w) <- runRWST m r s@@ -199,14 +255,20 @@ -- unchanged. -- -- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@+--+-- * @'runRWST' ('censor' f m) r s = 'liftM' (\\(a, w) -> (a, f w)) ('runRWST' m r s)@ censor :: (Monoid w, Monad m) => (w -> w) -> RWST r w s m a -> RWST r w s m a-censor f m = pass $ do- a <- m- return (a, f)+censor f m = RWST $ \r s -> do+ ~(a, s', w) <- runRWST m r s+ return (a, s', f w) -- --------------------------------------------------------------------------- -- State operations +-- | Construct a state monad computation from a state transformer function.+state :: (Monoid w, Monad m) => (s -> (a,s)) -> RWST r w s m a+state f = RWST $ \_ s -> let (a,s') = f s in return (a, s', mempty)+ -- | Fetch the current value of the state within the monad. get :: (Monoid w, Monad m) => RWST r w s m s get = RWST $ \_ s -> return (s, s, mempty)@@ -217,19 +279,17 @@ -- | @'modify' f@ is an action that updates the state to the result of -- applying @f@ to the current state.+--+-- * @'modify' f = 'get' >>= ('put' . f)@ modify :: (Monoid w, Monad m) => (s -> s) -> RWST r w s m ()-modify f = do- s <- get- put (f s)+modify f = RWST $ \_ s -> return ((), f s, mempty) -- | Get a specific component of the state, using a projection function -- supplied. -- -- * @'gets' f = 'liftM' f 'get'@ gets :: (Monoid w, Monad m) => (s -> a) -> RWST r w s m a-gets f = do- s <- get- return (f s)+gets f = RWST $ \_ s -> return (f s, s, mempty) -- | Uniform lifting of a @callCC@ operation to the new monad. -- This version rolls back to the original state on entering the
Control/Monad/Trans/RWS/Strict.hs view
@@ -30,16 +30,19 @@ mapRWST, withRWST, -- * Reader operations+ reader, ask, local, asks, -- * Writer operations+ writer, tell, listen, listens, pass, censor, -- * State operations+ state, get, put, modify,@@ -73,19 +76,37 @@ runRWS :: RWS r w s a -> r -> s -> (a, s, w) runRWS m r s = runIdentity (runRWST m r s) -evalRWS :: RWS r w s a -> r -> s -> (a, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final value and output, discarding the final state.+evalRWS :: RWS r w s a -- ^RWS computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> (a, w) -- ^final value and output evalRWS m r s = let (a, _, w) = runRWS m r s in (a, w) -execRWS :: RWS r w s a -> r -> s -> (s, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final state and output, discarding the final value.+execRWS :: RWS r w s a -- ^RWS computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> (s, w) -- ^final state and output execRWS m r s = let (_, s', w) = runRWS m r s in (s', w) +-- | Map the return value, final state and output of a computation using+-- the given function.+--+-- * @'runRWS' ('mapRWS' f m) r s = f ('runRWS' m r s)@ mapRWS :: ((a, s, w) -> (b, s, w')) -> RWS r w s a -> RWS r w' s b mapRWS f = mapRWST (Identity . f . runIdentity) +-- | @'withRWS' f m@ executes action @m@ with an initial environment+-- and state modified by applying @f@.+--+-- * @'runRWS' ('withRWS' f m) r s = 'uncurry' ('runRWS' m) (f r s)@ withRWS :: (r' -> s -> (r, s)) -> RWS r w s a -> RWS r' w s a withRWS = withRWST @@ -95,19 +116,38 @@ -- to an inner monad @m@. newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) } -evalRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (a, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final value and output, discarding the final state.+evalRWST :: (Monad m)+ => RWST r w s m a -- ^computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> m (a, w) -- ^computation yielding final value and output evalRWST m r s = do (a, _, w) <- runRWST m r s return (a, w) -execRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (s, w)+-- | Evaluate a computation with the given initial state and environment,+-- returning the final state and output, discarding the final value.+execRWST :: (Monad m)+ => RWST r w s m a -- ^computation to execute+ -> r -- ^initial environment+ -> s -- ^initial value+ -> m (s, w) -- ^computation yielding final state and output execRWST m r s = do (_, s', w) <- runRWST m r s return (s', w) +-- | Map the inner computation using the given function.+--+-- * @'runRWST' ('mapRWST' f m) r s = f ('runRWST' m r s)@ mapRWST :: (m (a, s, w) -> n (b, s, w')) -> RWST r w s m a -> RWST r w' s n b mapRWST f m = RWST $ \r s -> f (runRWST m r s) +-- | @'withRWST' f m@ executes action @m@ with an initial environment+-- and state modified by applying @f@.+--+-- * @'runRWST' ('withRWST' f m) r s = 'uncurry' ('runRWST' m) (f r s)@ withRWST :: (r' -> s -> (r, s)) -> RWST r w s m a -> RWST r' w s m a withRWST f m = RWST $ \r s -> uncurry (runRWST m) (f r s) @@ -149,29 +189,41 @@ -- --------------------------------------------------------------------------- -- Reader operations +-- | Constructor for computations in the reader monad (equivalent to 'asks').+reader :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a+reader = asks+ -- | Fetch the value of the environment. ask :: (Monoid w, Monad m) => RWST r w s m r ask = RWST $ \r s -> return (r, s, mempty) -- | Execute a computation in a modified environment+--+-- * @'runRWST' ('local' f m) r s = 'runRWST' m (f r) s@ local :: (Monoid w, Monad m) => (r -> r) -> RWST r w s m a -> RWST r w s m a local f m = RWST $ \r s -> runRWST m (f r) s -- | Retrieve a function of the current environment.+--+-- * @'asks' f = 'liftM' f 'ask'@ asks :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a-asks f = do- r <- ask- return (f r)+asks f = RWST $ \r s -> return (f r, s, mempty) -- --------------------------------------------------------------------------- -- Writer operations +-- | Construct a writer computation from a (result, output) pair.+writer :: Monad m => (a, w) -> RWST r w s m a+writer (a, w) = RWST $ \_ s -> return (a, s, w)+ -- | @'tell' w@ is an action that produces the output @w@. tell :: (Monoid w, Monad m) => w -> RWST r w s m () tell w = RWST $ \_ s -> return ((),s,w) -- | @'listen' m@ is an action that executes the action @m@ and adds its -- output to the value of the computation.+--+-- * @'runRWST' ('listen' m) r s = 'liftM' (\\(a, w) -> ((a, w), w)) ('runRWST' m r s)@ listen :: (Monoid w, Monad m) => RWST r w s m a -> RWST r w s m (a, w) listen m = RWST $ \r s -> do (a, s', w) <- runRWST m r s@@ -181,14 +233,18 @@ -- the result of applying @f@ to the output to the value of the computation. -- -- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@+--+-- * @'runRWST' ('listens' f m) r s = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runRWST' m r s)@ listens :: (Monoid w, Monad m) => (w -> b) -> RWST r w s m a -> RWST r w s m (a, b)-listens f m = do- (a, w) <- listen m- return (a, f w)+listens f m = RWST $ \r s -> do+ (a, s', w) <- runRWST m r s+ return ((a, f w), s', w) -- | @'pass' m@ is an action that executes the action @m@, which returns -- a value and a function, and returns the value, applying the function -- to the output.+--+-- * @'runRWST' ('pass' m) r s = 'liftM' (\\((a, f), w) -> (a, f w)) ('runRWST' m r s)@ pass :: (Monoid w, Monad m) => RWST r w s m (a, w -> w) -> RWST r w s m a pass m = RWST $ \r s -> do ((a, f), s', w) <- runRWST m r s@@ -199,14 +255,20 @@ -- unchanged. -- -- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@+--+-- * @'runRWST' ('censor' f m) r s = 'liftM' (\\(a, w) -> (a, f w)) ('runRWST' m r s)@ censor :: (Monoid w, Monad m) => (w -> w) -> RWST r w s m a -> RWST r w s m a-censor f m = pass $ do- a <- m- return (a, f)+censor f m = RWST $ \r s -> do+ (a, s', w) <- runRWST m r s+ return (a, s', f w) -- --------------------------------------------------------------------------- -- State operations +-- | Construct a state monad computation from a state transformer function.+state :: (Monoid w, Monad m) => (s -> (a,s)) -> RWST r w s m a+state f = RWST $ \_ s -> case f s of (a,s') -> return (a, s', mempty)+ -- | Fetch the current value of the state within the monad. get :: (Monoid w, Monad m) => RWST r w s m s get = RWST $ \_ s -> return (s, s, mempty)@@ -217,19 +279,17 @@ -- | @'modify' f@ is an action that updates the state to the result of -- applying @f@ to the current state.+--+-- * @'modify' f = 'get' >>= ('put' . f)@ modify :: (Monoid w, Monad m) => (s -> s) -> RWST r w s m ()-modify f = do- s <- get- put (f s)+modify f = RWST $ \_ s -> return ((), f s, mempty) -- | Get a specific component of the state, using a projection function -- supplied. -- -- * @'gets' f = 'liftM' f 'get'@ gets :: (Monoid w, Monad m) => (s -> a) -> RWST r w s m a-gets f = do- s <- get- return (f s)+gets f = RWST $ \_ s -> return (f s, s, mempty) -- | Uniform lifting of a @callCC@ operation to the new monad. -- This version rolls back to the original state on entering the
Control/Monad/Trans/Reader.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : Control.Monad.Trans.Reader@@ -44,9 +43,7 @@ import Control.Applicative import Control.Monad import Control.Monad.Fix-#if !(MIN_VERSION_base(4,6,0))-import Control.Monad.Instances () -- deprecated from base-4.6-#endif+import Control.Monad.Instances () -- | The parameterizable reader monad. --@@ -56,22 +53,27 @@ -- the inherited environment to both subcomputations. type Reader r = ReaderT r Identity --- | Constructor for computations in the reader monad.-reader :: (r -> a) -> Reader r a-reader f = ReaderT (Identity . f)+-- | Constructor for computations in the reader monad (equivalent to 'asks').+reader :: Monad m => (r -> a) -> ReaderT r m a+reader f = ReaderT (return . f) -- | Runs a @Reader@ and extracts the final value from it.+-- (The inverse of 'reader'.) runReader :: Reader r a -- ^ A @Reader@ to run. -> r -- ^ An initial environment. -> a runReader m = runIdentity . runReaderT m -- | Transform the value returned by a @Reader@.+--+-- * @'runReader' ('mapReader' f m) = f . 'runReader' m@ mapReader :: (a -> b) -> Reader r a -> Reader r b mapReader f = mapReaderT (Identity . f . runIdentity) -- | Execute a computation in a modified environment -- (a specialization of 'withReaderT').+--+-- * @'runReader' ('withReader' f m) = 'runReader' m . f@ withReader :: (r' -> r) -- ^ The function to modify the environment. -> Reader r a -- ^ Computation to run in the modified environment.@@ -89,11 +91,15 @@ } -- | Transform the computation inside a @ReaderT@.+--+-- * @'runReaderT' ('mapReaderT' f m) = f . 'runReaderT' m@ mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b mapReaderT f m = ReaderT $ f . runReaderT m -- | Execute a computation in a modified environment--- (a more general version of 'local').+-- (a more general version of 'local').+--+-- * @'runReaderT' ('withReaderT' f m) = 'runReaderT' m . f@ withReaderT :: (r' -> r) -- ^ The function to modify the environment. -> ReaderT r m a -- ^ Computation to run in the modified environment.@@ -140,6 +146,8 @@ -- | Execute a computation in a modified environment -- (a specialization of 'withReaderT').+--+-- * @'runReaderT' ('local' f m) = 'runReaderT' m . f@ local :: (Monad m) => (r -> r) -- ^ The function to modify the environment. -> ReaderT r m a -- ^ Computation to run in the modified environment.@@ -147,10 +155,12 @@ local = withReaderT -- | Retrieve a function of the current environment.+--+-- * @'asks' f = 'liftM' f 'ask'@ asks :: (Monad m) => (r -> a) -- ^ The selector function to apply to the environment. -> ReaderT r m a-asks f = liftM f ask+asks f = ReaderT (return . f) -- | Lift a @callCC@ operation to the new monad. liftCallCC ::
Control/Monad/Trans/State.hs view
@@ -9,7 +9,7 @@ -- Stability : experimental -- Portability : portable ----- State monads, passing an updateable state through a computation.+-- State monads, passing an updatable state through a computation. -- -- Some computations may not require the full power of state transformers: --
Control/Monad/Trans/State/Lazy.hs view
@@ -9,11 +9,11 @@ -- Stability : experimental -- Portability : portable ----- Lazy state monads, passing an updateable state through a computation.+-- Lazy state monads, passing an updatable state through a computation. -- See below for examples. ----- In this version, sequencing of computations is lazy in the state.--- For a strict version, see "Control.Monad.Trans.Writer.Strict", which+-- In this version, sequencing of computations is lazy.+-- For a strict version, see "Control.Monad.Trans.State.Strict", which -- has the same interface. -- -- Some computations may not require the full power of state transformers:@@ -79,9 +79,10 @@ -- | Construct a state monad computation from a function. -- (The inverse of 'runState'.)-state :: (s -> (a, s)) -- ^pure state transformer- -> State s a -- ^equivalent state-passing computation-state f = StateT (Identity . f)+state :: Monad m+ => (s -> (a, s)) -- ^pure state transformer+ -> StateT s m a -- ^equivalent state-passing computation+state f = StateT (return . f) -- | Unwrap a state monad computation as a function. -- (The inverse of 'state'.)@@ -179,7 +180,7 @@ (<|>) = mplus instance (Monad m) => Monad (StateT s m) where- return a = StateT $ \s -> return (a, s)+ return a = state $ \s -> (a, s) m >>= k = StateT $ \s -> do ~(a, s') <- runStateT m s runStateT (k a) s'@@ -202,27 +203,25 @@ -- | Fetch the current value of the state within the monad. get :: (Monad m) => StateT s m s-get = StateT $ \s -> return (s, s)+get = state $ \s -> (s, s) -- | @'put' s@ sets the state within the monad to @s@. put :: (Monad m) => s -> StateT s m ()-put s = StateT $ \_ -> return ((), s)+put s = state $ \_ -> ((), s) -- | @'modify' f@ is an action that updates the state to the result of -- applying @f@ to the current state.+--+-- * @'modify' f = 'get' >>= ('put' . f)@ modify :: (Monad m) => (s -> s) -> StateT s m ()-modify f = do- s <- get- put (f s)+modify f = state $ \s -> ((), f s) -- | Get a specific component of the state, using a projection function -- supplied. -- -- * @'gets' f = 'liftM' f 'get'@ gets :: (Monad m) => (s -> a) -> StateT s m a-gets f = do- s <- get- return (f s)+gets f = state $ \s -> (f s, s) -- | Uniform lifting of a @callCC@ operation to the new monad. -- This version rolls back to the original state on entering the@@ -288,9 +287,9 @@ {- $counting -A function to increment a counter. Taken from the paper-/Generalising Monads to Arrows/, John-Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:+A function to increment a counter.+Taken from the paper \"Generalising Monads to Arrows\",+John Hughes (<http://www.cse.chalmers.se/~rjmh/>), November 1998: > tick :: State Int Int > tick = do n <- get
Control/Monad/Trans/State/Strict.hs view
@@ -9,11 +9,11 @@ -- Stability : experimental -- Portability : portable ----- Strict state monads, passing an updateable state through a computation.+-- Strict state monads, passing an updatable state through a computation. -- See below for examples. ----- In this version, sequencing of computations is strict in the state.--- For a lazy version, see "Control.Monad.Trans.Writer.Lazy", which+-- In this version, sequencing of computations is strict.+-- For a lazy version, see "Control.Monad.Trans.State.Lazy", which -- has the same interface. -- -- Some computations may not require the full power of state transformers:@@ -79,9 +79,10 @@ -- | Construct a state monad computation from a function. -- (The inverse of 'runState'.)-state :: (s -> (a, s)) -- ^pure state transformer- -> State s a -- ^equivalent state-passing computation-state f = StateT (Identity . f)+state :: Monad m+ => (s -> (a, s)) -- ^pure state transformer+ -> StateT s m a -- ^equivalent state-passing computation+state f = StateT (return . f) -- | Unwrap a state monad computation as a function. -- (The inverse of 'state'.)@@ -179,7 +180,7 @@ (<|>) = mplus instance (Monad m) => Monad (StateT s m) where- return a = StateT $ \s -> return (a, s)+ return a = state $ \s -> (a, s) m >>= k = StateT $ \s -> do (a, s') <- runStateT m s runStateT (k a) s'@@ -202,27 +203,25 @@ -- | Fetch the current value of the state within the monad. get :: (Monad m) => StateT s m s-get = StateT $ \s -> return (s, s)+get = state $ \s -> (s, s) -- | @'put' s@ sets the state within the monad to @s@. put :: (Monad m) => s -> StateT s m ()-put s = StateT $ \_ -> return ((), s)+put s = state $ \_ -> ((), s) -- | @'modify' f@ is an action that updates the state to the result of -- applying @f@ to the current state.+--+-- * @'modify' f = 'get' >>= ('put' . f)@ modify :: (Monad m) => (s -> s) -> StateT s m ()-modify f = do- s <- get- put (f s)+modify f = state $ \s -> ((), f s) -- | Get a specific component of the state, using a projection function -- supplied. -- -- * @'gets' f = 'liftM' f 'get'@ gets :: (Monad m) => (s -> a) -> StateT s m a-gets f = do- s <- get- return (f s)+gets f = state $ \s -> (f s, s) -- | Uniform lifting of a @callCC@ operation to the new monad. -- This version rolls back to the original state on entering the@@ -288,9 +287,9 @@ {- $counting -A function to increment a counter. Taken from the paper-/Generalising Monads to Arrows/, John-Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:+A function to increment a counter.+Taken from the paper \"Generalising Monads to Arrows\",+John Hughes (<http://www.cse.chalmers.se/~rjmh/>), November 1998: > tick :: State Int Int > tick = do n <- get
Control/Monad/Trans/Writer/Lazy.hs view
@@ -49,7 +49,9 @@ import Control.Applicative import Control.Monad import Control.Monad.Fix+import Data.Foldable (Foldable(foldMap)) import Data.Monoid+import Data.Traversable (Traversable(traverse)) -- --------------------------------------------------------------------------- -- | A writer monad parameterized by the type @w@ of output to accumulate.@@ -60,8 +62,8 @@ -- | Construct a writer computation from a (result, output) pair. -- (The inverse of 'runWriter'.)-writer :: (a, w) -> Writer w a-writer = WriterT . Identity+writer :: Monad m => (a, w) -> WriterT w m a+writer = WriterT . return -- | Unwrap a writer computation as a (result, output) pair. -- (The inverse of 'writer'.)@@ -77,7 +79,7 @@ -- | Map both the return value and output of a computation using -- the given function. ----- * @'runWriter' ('mapWriter' f m) = f ('runWriter' m@)+-- * @'runWriter' ('mapWriter' f m) = f ('runWriter' m)@ mapWriter :: ((a, w) -> (b, w')) -> Writer w a -> Writer w' b mapWriter f = mapWriterT (Identity . f . runIdentity) @@ -103,7 +105,7 @@ -- | Map both the return value and output of a computation using -- the given function. ----- * @'runWriterT' ('mapWriterT' f m) = f ('runWriterT' m@)+-- * @'runWriterT' ('mapWriterT' f m) = f ('runWriterT' m)@ mapWriterT :: (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b mapWriterT f m = WriterT $ f (runWriterT m) @@ -120,7 +122,7 @@ m <|> n = WriterT $ runWriterT m <|> runWriterT n instance (Monoid w, Monad m) => Monad (WriterT w m) where- return a = WriterT $ return (a, mempty)+ return a = writer (a, mempty) m >>= k = WriterT $ do ~(a, w) <- runWriterT m ~(b, w') <- runWriterT (k a)@@ -142,9 +144,16 @@ instance (Monoid w, MonadIO m) => MonadIO (WriterT w m) where liftIO = lift . liftIO +instance Foldable f => Foldable (WriterT w f) where+ foldMap f (WriterT a) = foldMap (f . fst) a++instance Traversable f => Traversable (WriterT w f) where+ traverse f (WriterT a) = WriterT <$> traverse f' a where+ f' (a, b) = fmap (\c -> (c, b)) (f a)+ -- | @'tell' w@ is an action that produces the output @w@. tell :: (Monoid w, Monad m) => w -> WriterT w m ()-tell w = WriterT $ return ((), w)+tell w = writer ((), w) -- | @'listen' m@ is an action that executes the action @m@ and adds its -- output to the value of the computation.@@ -162,9 +171,9 @@ -- -- * @'runWriterT' ('listens' f m) = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runWriterT' m)@ listens :: (Monoid w, Monad m) => (w -> b) -> WriterT w m a -> WriterT w m (a, b)-listens f m = do- ~(a, w) <- listen m- return (a, f w)+listens f m = WriterT $ do+ ~(a, w) <- runWriterT m+ return ((a, f w), w) -- | @'pass' m@ is an action that executes the action @m@, which returns -- a value and a function, and returns the value, applying the function@@ -184,9 +193,9 @@ -- -- * @'runWriterT' ('censor' f m) = 'liftM' (\\(a, w) -> (a, f w)) ('runWriterT' m)@ censor :: (Monoid w, Monad m) => (w -> w) -> WriterT w m a -> WriterT w m a-censor f m = pass $ do- a <- m- return (a, f)+censor f m = WriterT $ do+ ~(a, w) <- runWriterT m+ return (a, f w) -- | Lift a @callCC@ operation to the new monad. liftCallCC :: (Monoid w) => ((((a,w) -> m (b,w)) -> m (a,w)) -> m (a,w)) ->
Control/Monad/Trans/Writer/Strict.hs view
@@ -49,7 +49,9 @@ import Control.Applicative import Control.Monad import Control.Monad.Fix+import Data.Foldable (Foldable(foldMap)) import Data.Monoid+import Data.Traversable (Traversable(traverse)) -- --------------------------------------------------------------------------- -- | A writer monad parameterized by the type @w@ of output to accumulate.@@ -60,8 +62,8 @@ -- | Construct a writer computation from a (result, output) pair. -- (The inverse of 'runWriter'.)-writer :: (a, w) -> Writer w a-writer = WriterT . Identity+writer :: Monad m => (a, w) -> WriterT w m a+writer = WriterT . return -- | Unwrap a writer computation as a (result, output) pair. -- (The inverse of 'writer'.)@@ -77,7 +79,7 @@ -- | Map both the return value and output of a computation using -- the given function. ----- * @'runWriter' ('mapWriter' f m) = f ('runWriter' m@)+-- * @'runWriter' ('mapWriter' f m) = f ('runWriter' m)@ mapWriter :: ((a, w) -> (b, w')) -> Writer w a -> Writer w' b mapWriter f = mapWriterT (Identity . f . runIdentity) @@ -103,13 +105,20 @@ -- | Map both the return value and output of a computation using -- the given function. ----- * @'runWriterT' ('mapWriterT' f m) = f ('runWriterT' m@)+-- * @'runWriterT' ('mapWriterT' f m) = f ('runWriterT' m)@ mapWriterT :: (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b mapWriterT f m = WriterT $ f (runWriterT m) instance (Functor m) => Functor (WriterT w m) where fmap f = mapWriterT $ fmap $ \ (a, w) -> (f a, w) +instance (Foldable f) => Foldable (WriterT w f) where+ foldMap f (WriterT a) = foldMap (f . fst) a++instance (Traversable f) => Traversable (WriterT w f) where+ traverse f (WriterT a) = WriterT <$> traverse f' a where+ f' (a, b) = fmap (\c -> (c, b)) (f a)+ instance (Monoid w, Applicative m) => Applicative (WriterT w m) where pure a = WriterT $ pure (a, mempty) f <*> v = WriterT $ liftA2 k (runWriterT f) (runWriterT v)@@ -162,9 +171,9 @@ -- -- * @'runWriterT' ('listens' f m) = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runWriterT' m)@ listens :: (Monoid w, Monad m) => (w -> b) -> WriterT w m a -> WriterT w m (a, b)-listens f m = do- (a, w) <- listen m- return (a, f w)+listens f m = WriterT $ do+ (a, w) <- runWriterT m+ return ((a, f w), w) -- | @'pass' m@ is an action that executes the action @m@, which returns -- a value and a function, and returns the value, applying the function@@ -184,9 +193,9 @@ -- -- * @'runWriterT' ('censor' f m) = 'liftM' (\\(a, w) -> (a, f w)) ('runWriterT' m)@ censor :: (Monoid w, Monad m) => (w -> w) -> WriterT w m a -> WriterT w m a-censor f m = pass $ do- a <- m- return (a, f)+censor f m = WriterT $ do+ (a, w) <- runWriterT m+ return (a, f w) -- | Lift a @callCC@ operation to the new monad. liftCallCC :: (Monoid w) => ((((a,w) -> m (b,w)) -> m (a,w)) -> m (a,w)) ->
Data/Functor/Identity.hs view
@@ -12,7 +12,7 @@ -- -- This trivial type constructor serves two purposes: ----- * It can be used with functions parameterized by a 'Functor' or 'Monad'.+-- * It can be used with functions parameterized by functor or monad classes. -- -- * It can be used as a base monad to which a series of monad -- transformers may be applied to construct a composite monad.
Data/Functor/Product.hs view
@@ -14,6 +14,8 @@ ) where import Control.Applicative+import Control.Monad (MonadPlus(..))+import Control.Monad.Fix (MonadFix(..)) import Data.Foldable (Foldable(foldMap)) import Data.Monoid (mappend) import Data.Traversable (Traversable(traverse))@@ -37,3 +39,20 @@ instance (Alternative f, Alternative g) => Alternative (Product f g) where empty = Pair empty empty Pair x1 y1 <|> Pair x2 y2 = Pair (x1 <|> x2) (y1 <|> y2)++instance (Monad f, Monad g) => Monad (Product f g) where+ return x = Pair (return x) (return x)+ Pair m n >>= f = Pair (m >>= fstP . f) (n >>= sndP . f)+ where+ fstP (Pair a _) = a+ sndP (Pair _ b) = b++instance (MonadPlus f, MonadPlus g) => MonadPlus (Product f g) where+ mzero = Pair mzero mzero+ Pair x1 y1 `mplus` Pair x2 y2 = Pair (x1 `mplus` x2) (y1 `mplus` y2)++instance (MonadFix f, MonadFix g) => MonadFix (Product f g) where+ mfix f = Pair (mfix (fstP . f)) (mfix (sndP . f))+ where+ fstP (Pair a _) = a+ sndP (Pair _ b) = b
+ Data/Functor/Reverse.hs view
@@ -0,0 +1,54 @@+-- |+-- Module : Data.Functor.Reverse+-- Copyright : (c) Russell O'Connor 2009+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- Making functors whose elements are notionally in the reverse order+-- from the original functor.++module Data.Functor.Reverse where++import Control.Applicative.Backwards++import Prelude hiding (foldr, foldr1, foldl, foldl1)+import Control.Applicative+import Data.Foldable+import Data.Traversable+import Data.Monoid++-- | The same functor, but with 'Foldable' and 'Traversable' instances+-- that process the elements in the reverse order.+newtype Reverse f a = Reverse { getReverse :: f a }++-- | Derived instance.+instance (Functor f) => Functor (Reverse f) where+ fmap f (Reverse a) = Reverse (fmap f a)++-- | Derived instance.+instance (Applicative f) => Applicative (Reverse f) where+ pure a = Reverse (pure a)+ Reverse f <*> Reverse a = Reverse (f <*> a)++-- | Derived instance.+instance (Alternative f) => Alternative (Reverse f) where+ empty = Reverse empty+ Reverse x <|> Reverse y = Reverse (x <|> y)++-- | Fold from right to left.+instance (Foldable f) => Foldable (Reverse f) where+ foldMap f (Reverse t) = getDual (foldMap (Dual . f) t)+ foldr f z (Reverse t) = foldl (flip f) z t+ foldl f z (Reverse t) = foldr (flip f) z t+ foldr1 f (Reverse t) = foldl1 (flip f) t+ foldl1 f (Reverse t) = foldr1 (flip f) t++-- | Traverse from right to left.+instance (Traversable f) => Traversable (Reverse f) where+ traverse f (Reverse t) =+ fmap Reverse . forwards $ traverse (Backwards . f) t+ sequenceA (Reverse t) =+ fmap Reverse . forwards $ sequenceA (fmap Backwards t)
transformers.cabal view
@@ -1,5 +1,5 @@ name: transformers-version: 0.2.2.1+version: 0.3.0.0 license: BSD3 license-file: LICENSE author: Andy Gill, Ross Paterson@@ -7,29 +7,43 @@ category: Control synopsis: Concrete functor and monad transformers description:- Haskell 98 part of a monad transformer library, inspired by the paper- \"Functional Programming with Overloading and Higher-Order Polymorphism\",- by Mark P Jones, in /Advanced School of Functional Programming/, 1995+ A portable library of functor and monad transformers, inspired by+ the paper \"Functional Programming with Overloading and Higher-Order+ Polymorphism\", by Mark P Jones,+ in /Advanced School of Functional Programming/, 1995 (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>). .- This part contains the monad transformer class, the concrete monad- transformers, operations and liftings. It can be used on its own- in Haskell 98 code, or with the monad classes in the @monads-fd@ or- @monads-tf@ packages, which automatically lift operations introduced- by monad transformers through other transformers.+ This package contains:+ .+ * the monad transformer class (in "Control.Monad.Trans.Class")+ .+ * concrete functor and monad transformers, each with associated+ operations and functions to lift operations associated with other+ transformers.+ .+ It can be used on its own in portable Haskell code, or with the monad+ classes in the @mtl@ or @monads-tf@ packages, which automatically+ lift operations introduced by monad transformers through other+ transformers. build-type: Simple-cabal-version: >= 1.5.5+cabal-version: >= 1.6 +source-repository head+ type: darcs+ location: http://code.haskell.org/~ross/transformers+ flag ApplicativeInBase- description: Choose the newer base package, including Applicative and other- Functor classes.+ description: Use the current base package, including Applicative and+ other Functor classes. library if flag(ApplicativeInBase) build-depends: base >= 2 && < 6 else- build-depends: base >= 1.0 && < 2, special-functors >=1.0 && <1.1+ build-depends: base >= 1.0 && < 2, special-functors >= 1.0 && < 1.1 exposed-modules:+ Control.Applicative.Backwards+ Control.Applicative.Lift Control.Monad.IO.Class Control.Monad.Trans.Class Control.Monad.Trans.Cont@@ -51,3 +65,4 @@ Data.Functor.Constant Data.Functor.Identity Data.Functor.Product+ Data.Functor.Reverse