packages feed

quiver 0.0.0.6 → 0.0.0.7

raw patch · 4 files changed

+184/−79 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Control.Quiver: emit' :: b -> Consumer a' a f b' -> P a' a b b' f b'
- Control.Quiver: fetch' :: a' -> Producer b b' f a -> P a' a b b' f a
- Control.Quiver: qconcat_ :: SP [a] a f [a]
- Control.Quiver: qpure_ :: (a -> b) -> SP a b f ()
- Control.Quiver: type SP a b f r = forall b'. P () a b b' f r
- Control.Quiver.Internal: instance Applicative f => Applicative (P a' a b b' f)
- Control.Quiver.Internal: instance Functor f => Functor (P a' a b b' f)
- Control.Quiver.Internal: instance Monad f => Monad (P a' a b b' f)
- Control.Quiver.Internal: type SP a b f r = forall b'. P () a b b' f r
+ Control.Quiver: (>&>) :: Functor f => P a a' b b' f r -> (r -> r') -> P a a' b b' f r'
+ Control.Quiver: fetch_ :: a -> P a a' b b' f ()
+ Control.Quiver: qcompose :: Functor f => (r1 -> r2 -> r) -> P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f r
+ Control.Quiver.Internal: instance Applicative f => Applicative (P a a' b b' f)
+ Control.Quiver.Internal: instance Functor f => Functor (P a a' b b' f)
+ Control.Quiver.Internal: instance Monad f => Monad (P a a' b b' f)
+ Control.Quiver.SP: spconcat :: SP [a] a f [a]
+ Control.Quiver.SP: spfetch :: Functor f => SP a b f (Maybe a)
+ Control.Quiver.SP: spfold :: (Functor f, Monoid a) => SP a a f ()
+ Control.Quiver.SP: spfoldl :: (b -> a -> b) -> b -> SP a b f ()
+ Control.Quiver.SP: spfoldr :: (a -> b -> b) -> b -> SP a b f ()
+ Control.Quiver.SP: spid :: SP a a f ()
+ Control.Quiver.SP: sppure :: (a -> b) -> SP a b f ()
+ Control.Quiver.SP: type SP a b f r = forall b'. P () a b b' f r
+ Control.Quiver.SP: type SPResult e = Maybe (Maybe e)
- Control.Quiver: (>->>) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)
+ Control.Quiver: (>->>) :: Functor f => P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f (r1, r2)
- Control.Quiver: (>>->) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)
+ Control.Quiver: (>>->) :: Functor f => P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f (r1, r2)
- Control.Quiver: consume :: a' -> (a -> P a' a b b' f r) -> Producer b b' f r -> P a' a b b' f r
+ Control.Quiver: consume :: a -> (a' -> P a a' b b' f r) -> Producer b b' f r -> P a a' b b' f r
- Control.Quiver: data P a' a b b' f r
+ Control.Quiver: data P a a' b b' f r
- Control.Quiver: decouple :: Functor f => P a' a b b' f r -> Producer b b' f r
+ Control.Quiver: decouple :: Functor f => P a a' b b' f r -> Producer b b' f r
- Control.Quiver: deliver :: r -> P a' a b b' f r
+ Control.Quiver: deliver :: r -> P a a' b b' f r
- Control.Quiver: deplete :: Functor f => P a' a b b' f r -> Consumer a' a f r
+ Control.Quiver: deplete :: Functor f => P a a' b b' f r -> Consumer a a' f r
- Control.Quiver: emit :: b -> P a' a b b' f (Maybe b')
+ Control.Quiver: emit :: b -> P a a' b b' f (Maybe b')
- Control.Quiver: emit_ :: b -> P a' a b b' f ()
+ Control.Quiver: emit_ :: b -> P a a' b b' f ()
- Control.Quiver: enclose :: f (P a' a b b' f r) -> P a' a b b' f r
+ Control.Quiver: enclose :: f (P a a' b b' f r) -> P a a' b b' f r
- Control.Quiver: fetch :: a' -> P a' a b b' f (Maybe a)
+ Control.Quiver: fetch :: Functor f => a -> P a a' b b' f (Maybe a')
- Control.Quiver: produce :: b -> (b' -> P a' a b b' f r) -> Consumer a' a f r -> P a' a b b' f r
+ Control.Quiver: produce :: b -> (b' -> P a a' b b' f r) -> Consumer a a' f r -> P a a' b b' f r
- Control.Quiver: qlift :: Functor f => f r -> P a' a b b' f r
+ Control.Quiver: qlift :: Functor f => f r -> P a a' b b' f r
- Control.Quiver: qpure :: (b' -> a') -> (a -> b) -> b' -> P a' a b b' f ()
+ Control.Quiver: qpure :: (b' -> a) -> (a' -> b) -> b' -> P a a' b b' f (Either a b)
- Control.Quiver: type Consumer a' a f r = forall b b'. P a' a b b' f r
+ Control.Quiver: type Consumer a a' f r = forall b b'. P a a' b b' f r
- Control.Quiver: type Effect f r = forall a' a b b'. P a' a b b' f r
+ Control.Quiver: type Effect f r = forall a a' b b'. P a a' b b' f r
- Control.Quiver: type Producer b b' f r = forall a' a. P a' a b b' f r
+ Control.Quiver: type Producer b b' f r = forall a a'. P a a' b b' f r
- Control.Quiver.Internal: [Consume] :: a' -> (a -> P a' a b b' f r) -> (Producer b b' f r) -> P a' a b b' f r
+ Control.Quiver.Internal: [Consume] :: a -> (a' -> P a a' b b' f r) -> (Producer b b' f r) -> P a a' b b' f r
- Control.Quiver.Internal: [Deliver] :: r -> P a' a b b' f r
+ Control.Quiver.Internal: [Deliver] :: r -> P a a' b b' f r
- Control.Quiver.Internal: [Enclose] :: (f (P a' a b b' f r)) -> P a' a b b' f r
+ Control.Quiver.Internal: [Enclose] :: (f (P a a' b b' f r)) -> P a a' b b' f r
- Control.Quiver.Internal: [Produce] :: b -> (b' -> P a' a b b' f r) -> (Consumer a' a f r) -> P a' a b b' f r
+ Control.Quiver.Internal: [Produce] :: b -> (b' -> P a a' b b' f r) -> (Consumer a a' f r) -> P a a' b b' f r
- Control.Quiver.Internal: consume :: a' -> (a -> P a' a b b' f r) -> Producer b b' f r -> P a' a b b' f r
+ Control.Quiver.Internal: consume :: a -> (a' -> P a a' b b' f r) -> Producer b b' f r -> P a a' b b' f r
- Control.Quiver.Internal: data P a' a b b' f r
+ Control.Quiver.Internal: data P a a' b b' f r
- Control.Quiver.Internal: decouple :: Functor f => P a' a b b' f r -> Producer b b' f r
+ Control.Quiver.Internal: decouple :: Functor f => P a a' b b' f r -> Producer b b' f r
- Control.Quiver.Internal: deliver :: r -> P a' a b b' f r
+ Control.Quiver.Internal: deliver :: r -> P a a' b b' f r
- Control.Quiver.Internal: deplete :: Functor f => P a' a b b' f r -> Consumer a' a f r
+ Control.Quiver.Internal: deplete :: Functor f => P a a' b b' f r -> Consumer a a' f r
- Control.Quiver.Internal: enclose :: f (P a' a b b' f r) -> P a' a b b' f r
+ Control.Quiver.Internal: enclose :: f (P a a' b b' f r) -> P a a' b b' f r
- Control.Quiver.Internal: produce :: b -> (b' -> P a' a b b' f r) -> Consumer a' a f r -> P a' a b b' f r
+ Control.Quiver.Internal: produce :: b -> (b' -> P a a' b b' f r) -> Consumer a a' f r -> P a a' b b' f r
- Control.Quiver.Internal: type Consumer a' a f r = forall b b'. P a' a b b' f r
+ Control.Quiver.Internal: type Consumer a a' f r = forall b b'. P a a' b b' f r
- Control.Quiver.Internal: type Effect f r = forall a' a b b'. P a' a b b' f r
+ Control.Quiver.Internal: type Effect f r = forall a a' b b'. P a a' b b' f r
- Control.Quiver.Internal: type Producer b b' f r = forall a' a. P a' a b b' f r
+ Control.Quiver.Internal: type Producer b b' f r = forall a a'. P a a' b b' f r

Files

quiver.cabal view
@@ -1,5 +1,5 @@ name:           quiver-version:        0.0.0.6+version:        0.0.0.7 synopsis:       Quiver finite stream processing library homepage:       https://github.com/zadarnowski/quiver category:       Control@@ -35,7 +35,7 @@ source-repository this   type:         git   location:     https://github.com/zadarnowski/quiver.git-  tag:          0.0.0.6+  tag:          0.0.0.7  library   hs-source-dirs:   src@@ -45,6 +45,7 @@   exposed-modules:     Control.Quiver     Control.Quiver.Internal+    Control.Quiver.SP    build-depends:     base >= 4.8 && < 5
src/Control/Quiver.lhs view
@@ -13,66 +13,56 @@  > module Control.Quiver ( >   -- Imported from @Control.Quiver.Internal@:->   P, SP, Consumer, Producer, Effect,+>   P, Consumer, Producer, Effect, >   consume, produce, enclose, deliver, >   decouple, deplete, >   -- Defined below:->   fetch, fetch',->   emit, emit', emit_,+>   fetch, fetch_,+>   emit, emit_, >   qlift,->   qpure, qpure_, qid,->   qconcat, qconcat_,+>   qpure, qid, qconcat, >   runEffect,->   (>>->), (>->>),+>   (>>->), (>->>), (>&>),+>   qcompose, > ) where  > import Control.Quiver.Internal -> infixl 0 >>->, >->>+> infixl 0 >>->, >->>, >&>  > -- | @fetch x@ represents a singleton stream processor that > --   sends the request value @x@ upstream and delivers the > --   next input value received, or @Nothing@ if the upstream > --   processor has been depleted. -> fetch :: a' -> P a' a b b' f (Maybe a)+> fetch :: Functor f => a -> P a a' b b' f (Maybe a') > fetch x = consume x (deliver . Just) (deliver Nothing) -> -- | @fetch' x q@ represents a singleton stream processor that-> --   sends the request value @x@ upstream and delivers the next-> --   input value received, or, if the upstream processor has-> --   been depleted, continues with the decoupled processor @q@.+> -- | @fetch_ x@ represents a singleton stream processor that+> --   sends the request value @x@ upstream, discarding any+> --   input received, for symmetry with @emit_@. -> fetch' :: a' -> Producer b b' f a -> P a' a b b' f a-> fetch' x q = consume x deliver q+> fetch_ :: a -> P a a' b b' f ()+> fetch_ x = consume x (deliver . const ()) (deliver ())  > -- | @emit y@ represents a singleton stream processor that > --   produces a single output value @y@ and delivers the > --   response received from the downstream processor, or > --   @Nothing@ if the downstream processor has been decoupled. -> emit :: b -> P a' a b b' f (Maybe b')+> emit :: b -> P a a' b b' f (Maybe b') > emit y = produce y (deliver . Just) (deliver Nothing) -> -- | @emit' y q@ represents a singleton stream processor that-> --   produces a single output value @y@ and delivers the-> --   response received from the downstream processor, or,-> --   if the downstream processor has been decoupled, continues-> --   with the depleted processor @q@.--> emit' :: b -> Consumer a' a f b' -> P a' a b b' f b'-> emit' y q = produce y deliver q--> -- | @emit' y q@ represents a singleton stream processor that+> -- | @emit_ y@ represents a singleton stream processor that > --   produces a single output value @y@, ignoring any response > --   received from the downstream processor. -> emit_ :: b -> P a' a b b' f ()+> emit_ :: b -> P a a' b b' f () > emit_ y = produce y (deliver . const ()) (deliver ())  > -- | @qlift@ lifts the value of a base functor into a stream processor. -> qlift :: Functor f => f r -> P a' a b b' f r+> qlift :: Functor f => f r -> P a a' b b' f r > qlift = enclose . fmap deliver  > -- | @qpure g f z@ produces an infinite consumer/producer that@@ -81,21 +71,11 @@ > --   into an upstream request; the initial request is obtained > --   by applying @g@ to the initial response value @z@. -> qpure :: (b' -> a') -> (a -> b) -> b' -> P a' a b b' f ()+> qpure :: (b' -> a) -> (a' -> b) -> b' -> P a a' b b' f (Either a b) > qpure g f = cloop >  where->   cloop y = let y' = g y in consume y' ploop (deliver ())->   ploop x = let x' = f x in produce x' cloop (deliver ())--> -- | @qpure_ f@ produces an infinite consumer/producer that-> --   uses a pure function @f@ to convert every input value into-> --   an output; equivalent to @qpure id f (const ())@.--> qpure_ :: (a -> b) -> SP a b f ()-> qpure_ f = cloop->  where->   cloop = consume () ploop (deliver ())->   ploop x = produce (f x) (const cloop) (deliver ())+>   cloop y = let y' = g y in consume y' ploop (deliver (Left y'))+>   ploop x = let x' = f x in produce x' cloop (deliver (Right x'))  > -- | A pull-based identity processor, equivalent to 'qpure id id'. @@ -116,15 +96,6 @@ >   ploop ys (x:xs) = produce x (\y -> ploop (y:ys) xs) (deliver (xs, reverse ys)) >   ploop ys [] = cloop (reverse ys) -> -- | A pull-based list flattening processor without requests.--> qconcat_ :: SP [a] a f [a]-> qconcat_ = cloop->  where->   cloop = consume () ploop (deliver [])->   ploop (x:xs) = produce x (const $ ploop xs) (deliver xs)->   ploop [] = cloop- > -- | Evaluates an /effect/, i.e., a processor that is both detached > --   and depleted and hence neither consumes nor produces any input, > --   returning its delivered value. The base functor must be a monad.@@ -144,7 +115,7 @@ > --   represents a non-commutative monad, any effects of @p2@ will be > --   observed before those of @p1@. -> (>>->) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)+> (>>->) :: Functor f => P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f (r1, r2) > (Consume x1 k1 q1) >>-> p2 = consume x1 ((>>-> p2) . k1) (q1 >>-> p2) > (Produce y1 k1 q1) >>-> p2 = loop p2 >  where@@ -166,7 +137,7 @@ > --   represents a non-commutative monad, any effects of @p1@ will be > --   observed before those of @p2@. -> (>->>) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)+> (>->>) :: Functor f => P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f (r1, r2) > p1 >->> (Consume x2 k2 q2) = loop p1 >  where >   loop  (Consume x1 k1 q1) = consume x1 (loop . k1) (loop' q1)@@ -180,3 +151,32 @@ > p1 >->> (Produce y2 k2 q2) = produce y2 ((p1 >->>) . k2) (p1 >->> q2) > p1 >->> (Enclose f2)       = enclose (fmap (p1 >->>) f2) > p1 >->> (Deliver r2)       = fmap (, r2) (deplete p1)++> -- | An infix version of @flip fmap@ with the same precedence and associativity+> --   as the stream processor composition operators '>->>' and '>>->', indended+> --   for idiomatic processing of composition deliverables using expressions+> --   such as @p >->> q >&> fst@.++> (>&>) :: Functor f => P a a' b b' f r -> (r -> r') -> P a a' b b' f r'+> (>&>) = flip fmap++> -- | The @qcompose f p q@ is precisely equivalent to @p >->> q >&> uncurry f@,+> --   but faster. A rewrite rule is included to replace applications of+> --   '>->>' followed by '>&>' into 'qcompose'.++> qcompose :: Functor f => (r1 -> r2 -> r) -> P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f r+> qcompose ff p1 (Consume x2 k2 q2) = loop p1+>  where+>   loop  (Consume x1 k1 q1) = consume x1 (loop . k1) (loop' q1)+>   loop  (Produce y1 k1  _) = qcompose ff (k1 x2) (k2 y1)+>   loop  (Enclose f1)       = enclose (fmap loop f1)+>   loop  (Deliver r1)       = fmap (ff r1) q2+>   loop' (Consume  _  _ q1) = loop' q1+>   loop' (Produce y1 k1  _) = qcompose ff (k1 x2) (k2 y1)+>   loop' (Enclose f1)       = enclose (fmap loop' f1)+>   loop' (Deliver r1)       = fmap (ff r1) q2+> qcompose ff p1 (Produce y2 k2 q2) = produce y2 ((qcompose ff p1) . k2) (qcompose ff p1 q2)+> qcompose ff p1 (Enclose f2)       = enclose (fmap (qcompose ff p1) f2)+> qcompose ff p1 (Deliver r2)       = fmap (flip ff r2) (deplete p1)++> {-# RULES "qcompose/fmap" forall p q f . fmap f (p >->> q) = qcompose (curry f) p q #-}
src/Control/Quiver/Internal.lhs view
@@ -28,7 +28,7 @@ > {-# LANGUAGE RankNTypes, TupleSections #-}  > module Control.Quiver.Internal (->   P (..), SP, Producer, Consumer, Effect,+>   P (..), Producer, Consumer, Effect, >   consume, produce, enclose, deliver, >   decouple, deplete, > ) where@@ -37,24 +37,24 @@   Data Types   ========== -> -- | The main Quiver /stream processor/ type @P a' a b b' f r@,+> -- | The main Quiver /stream processor/ type @P a a' b b' f r@, > --   representing a producer/consumer structure with /bidirectional/, > --   /bounded/ communication on both the upstream (consumer) and > --   downstream (producer) channel. The six type parameters have > --   the following intuitive meaning: > ---> --   * @a'@ is the type of a /request/ values sent by the stream+> --   * @a@ is the type of a /request/ values sent by the stream > --     processor to its upstream partner in order to receive the > --     next element of the input stream. > ---> --   * @a@ is the type of the actual information being consumed+> --   * @a'@ is the type of the actual information being consumed > --     by this stream processor (i.e., elements of its input stream.) > -- > --   * @b@ is the type of the actual information being produced > --     by this stream processor (i.e., elements of its output stream.) > -- > --   * @b'@ is the type of the /response/ values received from-> --     the downstream partner for each elemnet of the output+> --     the downstream partner for each element of the output > --     stream produced by this stream processor. > -- > --   * @f@ is the type of the stream processor's /base functor/;@@ -72,7 +72,7 @@ > --   only time will tell whether this generalisation has useful > --   applications in the real world. -> data P a' a b b' f r =+> data P a a' b b' f r =  >   -- | @Consume x k q@ represents a /consumer step/, in which >   --   the request @x@ is sent upstream and the returned input@@ -81,7 +81,7 @@ >   --   delivered its ultimate result, hence reaching the end >   --   of processing), to the /decoupled continuation/ @q@. ->   Consume a' (a -> P a' a b b' f r) (Producer b b' f r) |+>   Consume a (a' -> P a a' b b' f r) (Producer b b' f r) |  >   -- | @Produce y k q@ represent a /producer step/, in which >   --   the output value @y@ is sent downstream, and the returned@@ -90,56 +90,55 @@ >   --   (i.e., delivered its ultimate result, hence reaching the end >   --   of processing), to the /depleted continuation/ @q@. ->   Produce b  (b' -> P a' a b b' f r) (Consumer a' a f r) |+>   Produce b  (b' -> P a a' b b' f r) (Consumer a a' f r) |  >   -- | @Enclose@ allows for selective application of the base >   --   functor @f@ the the remainder of the computation. ->   Enclose (f (P a' a b b' f r)) |+>   Enclose (f (P a a' b b' f r)) |  >   -- | @Deliver r@ completes processing of information, delivering >   --   its ultimate result @r@.  >   Deliver r -> -- | A /simple processor/ with a unit request type and an unspecified-> --   response type:--> type SP a b f r = forall b' . P () a b b' f r- > -- | A Quiver /producer/, represented by a stream processor > --   with unspecified input types. -> type Producer b b' f r = forall a' a . P a' a b b' f r+> type Producer b b' f r = forall a a' . P a a' b b' f r  > -- | A Quiver /consumer/, represented by a stream processor > --   with unspecified output types. -> type Consumer a' a f r = forall b b' . P a' a b b' f r+> type Consumer a a' f r = forall b b' . P a a' b b' f r  > -- | A Quiver /effect/, represented by a stream processor > --   with unspecified input and output types. -> type Effect f r = forall a' a b b' . P a' a b b' f r+> type Effect f r = forall a a' b b' . P a a' b b' f r     Instances   ========= -> instance Functor f => Functor (P a' a b b' f) where+> instance Functor f => Functor (P a a' b b' f) where >   fmap ff (Consume x k q) = Consume x (fmap ff . k) (fmap ff q) >   fmap ff (Produce y k q) = Produce y (fmap ff . k) (fmap ff q) >   fmap ff (Enclose f)     = Enclose (fmap (fmap ff) f) >   fmap ff (Deliver r)     = Deliver (ff r)+>   r <$ (Consume x k q) = Consume x ((r <$) . k) (r <$ q)+>   r <$ (Produce y k q) = Produce y ((r <$) . k) (r <$ q)+>   r <$ (Enclose f)     = Enclose (fmap (r <$) f)+>   r <$ (Deliver _)     = Deliver r -> instance Applicative f => Applicative (P a' a b b' f) where+> instance Applicative f => Applicative (P a a' b b' f) where >   pure = Deliver >   (Consume x k q) <*> p = Consume x ((<*> p) . k) (q <*> decouple p) >   (Produce y k q) <*> p = Produce y ((<*> p) . k) (q <*> deplete p) >   (Enclose f)     <*> p = Enclose (fmap (<*> p) f) >   (Deliver r)     <*> p = fmap r p -> instance Monad f => Monad (P a' a b b' f) where+> instance Monad f => Monad (P a a' b b' f) where >   (Consume x k q) >>= kk = Consume x ((>>= kk) . k) (q >>= decouple . kk) >   (Produce y k q) >>= kk = Produce y ((>>= kk) . k) (q >>= deplete . kk) >   (Enclose f)     >>= kk = Enclose (fmap (>>= kk) f)@@ -156,7 +155,7 @@ > --   delivered its ultimate result, hence reaching the end > --   of processing), to the /decoupled continuation/ @q@. -> consume :: a' -> (a -> P a' a b b' f r) -> Producer b b' f r -> P a' a b b' f r+> consume :: a -> (a' -> P a a' b b' f r) -> Producer b b' f r -> P a a' b b' f r > consume = Consume  > -- | @produce y k q@ represent a /producer step/, in which@@ -166,19 +165,19 @@ > --   (i.e., delivered its ultimate result, hence reaching the end > --   of processing), to the /depleted continuation/ @q@. -> produce :: b  -> (b' -> P a' a b b' f r) -> Consumer a' a f r -> P a' a b b' f r+> produce :: b -> (b' -> P a a' b b' f r) -> Consumer a a' f r -> P a a' b b' f r > produce = Produce  > -- | @enclose@ allows for selective application of the base > --   functor @f@ the the remainder of the computation. -> enclose :: f (P a' a b b' f r) -> P a' a b b' f r+> enclose :: f (P a a' b b' f r) -> P a a' b b' f r > enclose = Enclose  > -- | @deliver r@ completes processing of information, delivering > --   its ultimate result @r@. -> deliver :: r -> P a' a b b' f r+> deliver :: r -> P a a' b b' f r > deliver = Deliver  @@ -190,7 +189,7 @@ > --   effectively converting @p@ into a producer processor that no longer > --   expects to receive any input. -> decouple :: Functor f => P a' a b b' f r -> Producer b b' f r+> decouple :: Functor f => P a a' b b' f r -> Producer b b' f r > decouple (Consume _ _ q) = q > decouple (Produce y k q) = Produce y (decouple . k) (decouple q) > decouple (Enclose f) = Enclose (fmap decouple f)@@ -201,7 +200,7 @@ > --   effectively converting @p@ into a consumer processor that will never > --   produce any more output. -> deplete :: Functor f => P a' a b b' f r -> Consumer a' a f r+> deplete :: Functor f => P a a' b b' f r -> Consumer a a' f r > deplete (Consume x k q) = Consume x (deplete . k) (deplete q) > deplete (Produce _ _ q) = q > deplete (Enclose f) = Enclose (fmap deplete f)
+ src/Control/Quiver/SP.lhs view
@@ -0,0 +1,105 @@+> -- | Module:    Control.Quiver.SP+> -- Description: Simple stream processors+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- This module provides a definition of a /simple processor/+> -- with a unit request type and an unspecified acknowledgement+> -- type, together with a number of common combinators for their+> -- definitions.++> {-# LANGUAGE PatternSynonyms, RankNTypes, ScopedTypeVariables, TupleSections #-}++> module Control.Quiver.SP (+>   SP,+>   SPResult,+>   pattern SPIncomplete,+>   pattern SPComplete,+>   pattern SPFailed,+>   spfetch,+>   sppure, spid, spconcat,+>   spfold, spfoldl, spfoldr,+> ) where++> import Control.Quiver++> -- | A /simple processor/ with a unit request type and an unspecified+> --   response type:++> type SP a b f r = forall b' . P () a b b' f r++> -- | Simple processor result type.++> type SPResult e = Maybe (Maybe e)++> -- | Simple processor result value indicating premature termination of the consumer.++> pattern SPIncomplete = Nothing++> -- | Simple processor result value indicating successful processing of the entire input stream.++> pattern SPComplete = Just Nothing++> -- | Simple processor result value indicating unsuccessful processing of the input stream.++> pattern SPFailed e = Just (Just e)++> -- | @spfetch@ represents a singleton simple stream processor that+> --   sends the request value @x@ upstream and delivers the+> --   next input value received, or @Nothing@ if the upstream+> --   processor has been depleted.++> spfetch :: Functor f => SP a b f (Maybe a)+> spfetch = fetch ()++> -- | @sppure f@ produces an infinite consumer/producer that+> --   uses a pure function @f@ to convert every input value into+> --   an output; equivalent to @qpure id f (const ())@.++> sppure :: (a -> b) -> SP a b f ()+> sppure f = cloop+>  where+>   cloop = consume () ploop (deliver ())+>   ploop x = produce (f x) (const cloop) (deliver ())++> -- | A simple identity processor, equivalent to 'sppure id'.++> spid :: SP a a f ()+> spid = cloop+>  where+>   cloop = consume () ploop (deliver ())+>   ploop x = produce x (const cloop) (deliver ())++> -- | A simple list flattening processor requests.++> spconcat :: SP [a] a f [a]+> spconcat = cloop+>  where+>   cloop = consume () ploop (deliver [])+>   ploop (x:xs) = produce x (const $ ploop xs) (deliver xs)+>   ploop [] = cloop++> -- | A processor that folds an entire stream into a single value.++> spfold :: (Functor f, Monoid a) => SP a a f ()+> spfold = cloop mempty+>  where+>   cloop r = consume () (cloop . mappend r) (emit_ r)++> -- | A processor that folds an entire stream into a single value.++> spfoldl :: (b -> a -> b) -> b -> SP a b f ()+> spfoldl f = cloop+>  where+>   cloop r = consume () (cloop . f r) (emit_ r)++> -- | A processor that folds an entire stream into a single value.++> spfoldr :: (a -> b -> b) -> b -> SP a b f ()+> spfoldr f = cloop+>  where+>   cloop r = consume () (cloop . flip f r) (emit_ r)+