| Safe Haskell | Trustworthy |
|---|---|
| Language | Haskell2010 |
Pipes
Description
This module is the recommended entry point to the pipes library.
Read Pipes.Tutorial if you want a tutorial explaining how to use this library.
- data Proxy a' a b' b m r
- data X
- type Effect = Proxy X () () X
- type Effect' m r = forall x' x y' y. Proxy x' x y' y m r
- runEffect :: Monad m => Effect m r -> m r
- type Producer b = Proxy X () () b
- type Producer' b m r = forall x' x. Proxy x' x () b m r
- yield :: Monad m => a -> Producer' a m ()
- for :: Monad m => Proxy x' x b' b m a' -> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
- (~>) :: Monad m => (a -> Proxy x' x b' b m a') -> (b -> Proxy x' x c' c m b') -> a -> Proxy x' x c' c m a'
- (<~) :: Monad m => (b -> Proxy x' x c' c m b') -> (a -> Proxy x' x b' b m a') -> a -> Proxy x' x c' c m a'
- type Consumer a = Proxy () a () X
- type Consumer' a m r = forall y' y. Proxy () a y' y m r
- await :: Monad m => Consumer' a m a
- (>~) :: Monad m => Proxy a' a y' y m b -> Proxy () b y' y m c -> Proxy a' a y' y m c
- (~<) :: Monad m => Proxy () b y' y m c -> Proxy a' a y' y m b -> Proxy a' a y' y m c
- type Pipe a b = Proxy () a () b
- cat :: Monad m => Pipe a a m r
- (>->) :: Monad m => Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
- (<-<) :: Monad m => Proxy () b c' c m r -> Proxy a' a () b m r -> Proxy a' a c' c m r
- newtype ListT m a = Select {}
- runListT :: Monad m => ListT m a -> m ()
- class Enumerable t where
- next :: Monad m => Producer a m r -> m (Either r (a, Producer a m r))
- each :: (Monad m, Foldable f) => f a -> Producer' a m ()
- every :: (Monad m, Enumerable t) => t m a -> Producer' a m ()
- discard :: Monad m => a -> m ()
- module Control.Monad
- module Control.Monad.IO.Class
- module Control.Monad.Trans.Class
- module Control.Monad.Morph
- class Foldable t
The Proxy Monad Transformer
data Proxy a' a b' b m r Source #
A Proxy is a monad transformer that receives and sends information on both
an upstream and downstream interface.
The type variables signify:
a'anda- The upstream interface, where(a')s go out and(a)s come inb'andb- The downstream interface, where(b)s go out and(b')s come inm- The base monadr- The return value
Instances
| MonadError e m => MonadError e (Proxy a' a b' b m) Source # | |
| MonadReader r m => MonadReader r (Proxy a' a b' b m) Source # | |
| MonadState s m => MonadState s (Proxy a' a b' b m) Source # | |
| MonadWriter w m => MonadWriter w (Proxy a' a b' b m) Source # | |
| MFunctor (Proxy a' a b' b) Source # | |
| MMonad (Proxy a' a b' b) Source # | |
| MonadTrans (Proxy a' a b' b) Source # | |
| Monad m => Monad (Proxy a' a b' b m) Source # | |
| Monad m => Functor (Proxy a' a b' b m) Source # | |
| Monad m => Applicative (Proxy a' a b' b m) Source # | |
| MonadIO m => MonadIO (Proxy a' a b' b m) Source # | |
| MonadPlus m => Alternative (Proxy a' a b' b m) Source # | |
| MonadPlus m => MonadPlus (Proxy a' a b' b m) Source # | |
| (Monad m, Monoid r) => Monoid (Proxy a' a b' b m r) Source # | |
The empty type, used to close output ends
When Data.Void is merged into base, this will change to:
type X = Void
type Effect' m r = forall x' x y' y. Proxy x' x y' y m r Source #
Like Effect, but with a polymorphic type
runEffect :: Monad m => Effect m r -> m r Source #
Run a self-contained Effect, converting it back to the base monad
Producers
Use yield to produce output and (~>) / for to substitute yields.
yield and (~>) obey the Category laws:
-- Substituting 'yield' with 'f' gives 'f'yield~>f = f -- Substituting every 'yield' with another 'yield' does nothing f~>yield= f -- 'yield' substitution is associative (f~>g)~>h = f~>(g~>h)
These are equivalent to the following "for loop laws":
-- Looping over a single yield simplifies to function applicationfor(yieldx) f = f x -- Re-yielding every element of a stream returns the original streamforsyield= s -- Nested for loops can become a sequentialforloops if the inner loop -- body ignores the outer loop variablefors (\a ->for(f a) g) =for(fors f) g =fors (f~>g)
type Producer' b m r = forall x' x. Proxy x' x () b m r Source #
Like Producer, but with a polymorphic type
(for p body) loops over p replacing each yield with body.
for::Monadm =>Producerb m r -> (b ->Effectm ()) ->Effectm rfor::Monadm =>Producerb m r -> (b ->Producerc m ()) ->Producerc m rfor::Monadm =>Pipex b m r -> (b ->Consumerx m ()) ->Consumerx m rfor::Monadm =>Pipex b m r -> (b ->Pipex c m ()) ->Pipex c m r
The following diagrams show the flow of information:
.---> b
/ |
+-----------+ / +-----|-----+ +---------------+
| | / | v | | |
| | / | | | |
x ==> p ==> b ---' x ==> body ==> c = x ==> for p body ==> c
| | | | | |
| | | | | | | | |
+-----|-----+ +-----|-----+ +-------|-------+
v v v
r () r
For a more complete diagram including bidirectional flow, see Pipes.Core.
Arguments
| :: Monad m | |
| => (a -> Proxy x' x b' b m a') | |
| -> (b -> Proxy x' x c' c m b') | |
| -> a -> Proxy x' x c' c m a' |
Compose loop bodies
(~>) ::Monadm => (a ->Producerb m r) -> (b ->Effectm ()) -> (a ->Effectm r) (~>) ::Monadm => (a ->Producerb m r) -> (b ->Producerc m ()) -> (a ->Producerc m r) (~>) ::Monadm => (a ->Pipex b m r) -> (b ->Consumerx m ()) -> (a ->Consumerx m r) (~>) ::Monadm => (a ->Pipex b m r) -> (b ->Pipex c m ()) -> (a ->Pipex c m r)
The following diagrams show the flow of information:
a .---> b a
| / | |
+-----|-----+ / +-----|-----+ +------|------+
| v | / | v | | v |
| | / | | | |
x ==> f ==> b ---' x ==> g ==> c = x ==> f ~> g ==> c
| | | | | |
| | | | | | | | |
+-----|-----+ +-----|-----+ +------|------+
v v v
r () r
For a more complete diagram including bidirectional flow, see Pipes.Core.
Arguments
| :: Monad m | |
| => (b -> Proxy x' x c' c m b') | |
| -> (a -> Proxy x' x b' b m a') | |
| -> a -> Proxy x' x c' c m a' |
(~>) with the arguments flipped
Consumers
Use await to request input and (>~) to substitute awaits.
await and (>~) obey the Category laws:
-- Substituting every 'await' with another 'await' does nothingawait>~f = f -- Substituting 'await' with 'f' gives 'f' f>~await= f -- 'await' substitution is associative (f>~g)>~h = f>~(g>~h)
type Consumer' a m r = forall y' y. Proxy () a y' y m r Source #
Like Consumer, but with a polymorphic type
(draw >~ p) loops over p replacing each await with draw
(>~) ::Monadm =>Effectm b ->Consumerb m c ->Effectm c (>~) ::Monadm =>Consumera m b ->Consumerb m c ->Consumera m c (>~) ::Monadm =>Producery m b ->Pipeb y m c ->Producery m c (>~) ::Monadm =>Pipea y m b ->Pipeb y m c ->Pipea y m c
The following diagrams show the flow of information:
+-----------+ +-----------+ +-------------+
| | | | | |
| | | | | |
a ==> f ==> y .---> b ==> g ==> y = a ==> f >~ g ==> y
| | / | | | |
| | | / | | | | | |
+-----|-----+ / +-----|-----+ +------|------+
v / v v
b ----' c c
For a more complete diagram including bidirectional flow, see Pipes.Core.
(>~) with the arguments flipped
Pipes
Use await and yield to build Pipes and (>->) to connect Pipes.
cat and (>->) obey the Category laws:
-- Useless use of catcat>->f = f -- Redirecting output to cat does nothing f>->cat= f -- The pipe operator is associative (f>->g)>->h = f>->(g>->h)
Pipe composition, analogous to the Unix pipe operator
(>->) ::Monadm =>Producerb m r ->Consumerb m r ->Effectm r (>->) ::Monadm =>Producerb m r ->Pipeb c m r ->Producerc m r (>->) ::Monadm =>Pipea b m r ->Consumerb m r ->Consumera m r (>->) ::Monadm =>Pipea b m r ->Pipeb c m r ->Pipea c m r
The following diagrams show the flow of information:
+-----------+ +-----------+ +-------------+
| | | | | |
| | | | | |
a ==> f ==> b ==> g ==> c = a ==> f >-> g ==> c
| | | | | |
| | | | | | | | |
+-----|-----+ +-----|-----+ +------|------+
v v v
r r r
For a more complete diagram including bidirectional flow, see Pipes.Core.
(>->) with the arguments flipped
ListT
The list monad transformer, which extends a monad with non-determinism
return corresponds to yield, yielding a single value
(>>=) corresponds to for, calling the second computation once for each
time the first computation yields.
Instances
| MFunctor ListT Source # | |
| MonadTrans ListT Source # | |
| Enumerable ListT Source # | |
| MonadError e m => MonadError e (ListT m) Source # | |
| MonadReader i m => MonadReader i (ListT m) Source # | |
| MonadState s m => MonadState s (ListT m) Source # | |
| MonadWriter w m => MonadWriter w (ListT m) Source # | |
| Monad m => Monad (ListT m) Source # | |
| Monad m => Functor (ListT m) Source # | |
| Monad m => Applicative (ListT m) Source # | |
| Foldable m => Foldable (ListT m) Source # | |
| MonadIO m => MonadIO (ListT m) Source # | |
| Monad m => Alternative (ListT m) Source # | |
| Monad m => MonadPlus (ListT m) Source # | |
| Monad m => Monoid (ListT m a) Source # | |
class Enumerable t where Source #
Enumerable generalizes Foldable, converting effectful
containers to ListTs.
Instances of Enumerable must satisfy these two laws:
toListT (return r) = return r
toListT $ do x <- m = do x <- toListT m
f x toListT (f x)In other words, toListT is monad morphism.
Minimal complete definition
Instances
Utilities
every :: (Monad m, Enumerable t) => t m a -> Producer' a m () Source #
Convert an Enumerable to a Producer
Re-exports
Control.Monad re-exports void
Control.Monad.IO.Class re-exports MonadIO.
Control.Monad.Trans.Class re-exports MonadTrans.
Control.Monad.Morph re-exports MFunctor.
Data.Foldable re-exports Foldable (the class name only).
module Control.Monad
module Control.Monad.IO.Class
module Control.Monad.Trans.Class
module Control.Monad.Morph
Data structures that can be folded.
For example, given a data type
data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)
a suitable instance would be
instance Foldable Tree where foldMap f Empty = mempty foldMap f (Leaf x) = f x foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r
This is suitable even for abstract types, as the monoid is assumed
to satisfy the monoid laws. Alternatively, one could define foldr:
instance Foldable Tree where foldr f z Empty = z foldr f z (Leaf x) = f x z foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l
Foldable instances are expected to satisfy the following laws:
foldr f z t = appEndo (foldMap (Endo . f) t ) z
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
fold = foldMap id
sum, product, maximum, and minimum should all be essentially
equivalent to foldMap forms, such as
sum = getSum . foldMap Sum
but may be less defined.
If the type is also a Functor instance, it should satisfy
foldMap f = fold . fmap f
which implies that
foldMap f . fmap g = foldMap (f . g)
Instances