Safe Haskell | Trustworthy |
---|---|
Language | Haskell2010 |
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
- type X = Void
- 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
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 # | |
MonadThrow m => MonadThrow (Proxy a' a b' b m) Source # | |
MonadCatch m => MonadCatch (Proxy a' a b' b m) Source # | |
(Monad m, Monoid r) => Monoid (Proxy a' a b' b m r) Source # | |
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 yield
s.
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
(yield
x) f = f x -- Re-yielding every element of a stream returns the original streamfor
syield
= s -- Nested for loops can become a sequentialfor
loops if the inner loop -- body ignores the outer loop variablefor
s (\a ->for
(f a) g) =for
(for
s f) g =for
s (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
::Monad
m =>Producer
b m r -> (b ->Effect
m ()) ->Effect
m rfor
::Monad
m =>Producer
b m r -> (b ->Producer
c m ()) ->Producer
c m rfor
::Monad
m =>Pipe
x b m r -> (b ->Consumer
x m ()) ->Consumer
x m rfor
::Monad
m =>Pipe
x b m r -> (b ->Pipe
x c m ()) ->Pipe
x 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.
:: 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
(~>
) ::Monad
m => (a ->Producer
b m r) -> (b ->Effect
m ()) -> (a ->Effect
m r) (~>
) ::Monad
m => (a ->Producer
b m r) -> (b ->Producer
c m ()) -> (a ->Producer
c m r) (~>
) ::Monad
m => (a ->Pipe
x b m r) -> (b ->Consumer
x m ()) -> (a ->Consumer
x m r) (~>
) ::Monad
m => (a ->Pipe
x b m r) -> (b ->Pipe
x c m ()) -> (a ->Pipe
x 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.
:: 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 await
s.
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
(>~
) ::Monad
m =>Effect
m b ->Consumer
b m c ->Effect
m c (>~
) ::Monad
m =>Consumer
a m b ->Consumer
b m c ->Consumer
a m c (>~
) ::Monad
m =>Producer
y m b ->Pipe
b y m c ->Producer
y m c (>~
) ::Monad
m =>Pipe
a y m b ->Pipe
b y m c ->Pipe
a 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 Pipe
s and (>->
) to connect Pipe
s.
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
(>->
) ::Monad
m =>Producer
b m r ->Consumer
b m r ->Effect
m r (>->
) ::Monad
m =>Producer
b m r ->Pipe
b c m r ->Producer
c m r (>->
) ::Monad
m =>Pipe
a b m r ->Consumer
b m r ->Consumer
a m r (>->
) ::Monad
m =>Pipe
a b m r ->Pipe
b c m r ->Pipe
a 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 yield
s.
MMonad 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 # | |
(Monad m, Traversable m) => Traversable (ListT m) Source # | |
Monad m => MonadZip (ListT m) Source # | |
MonadIO m => MonadIO (ListT m) Source # | |
Monad m => Alternative (ListT m) Source # | |
Monad m => MonadPlus (ListT m) Source # | |
MonadThrow m => MonadThrow (ListT m) Source # | |
MonadCatch m => MonadCatch (ListT m) Source # | |
MFunctor * ListT Source # | |
Monad m => Monoid (ListT m a) Source # | |
class Enumerable t where Source #
Enumerable
generalizes Foldable
, converting effectful
containers to ListT
s.
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.
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)