quiver 0.0.0.3 → 0.0.0.4
raw patch · 3 files changed
+86/−31 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Control.Quiver: liftP :: Functor f => f r -> P a' 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: qconcat :: [b] -> P [b] [a] a b f ([a], [b])
+ Control.Quiver: qconcat_ :: P () [a] a b f [a]
+ Control.Quiver: qid :: b -> P b a a b f ()
+ 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_ :: (a -> b) -> P () a b b' f ()
+ 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: (>->>) :: 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 -> Consumer a' a f b' -> P a' a b' b f b'
+ Control.Quiver: emit' :: b -> Consumer a' a f b' -> P a' a b b' f 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 :: a' -> P a' a b b' f (Maybe a)
- Control.Quiver: fetch' :: a' -> Producer b' b f a -> P a' a b' b f a
+ Control.Quiver: fetch' :: a' -> Producer b b' f a -> P a' a b b' f 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: 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 +2/−2
- src/Control/Quiver.lhs +63/−11
- src/Control/Quiver/Internal.lhs +21/−18
quiver.cabal view
@@ -1,5 +1,5 @@ name: quiver-version: 0.0.0.3+version: 0.0.0.4 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.3+ tag: 0.0.0.4 library hs-source-dirs: src
src/Control/Quiver.lhs view
@@ -19,7 +19,9 @@ > -- Defined below: > fetch, fetch', > emit, emit', emit_,-> liftP,+> qlift,+> qpure, qpure_, qid,+> qconcat, qconcat_, > runEffect, > (>>->), (>->>), > ) where@@ -33,7 +35,7 @@ > -- next input value received, or @Nothing@ if the upstream > -- processor has been depleted. -> fetch :: a' -> P a' a b' b f (Maybe a)+> fetch :: 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@@ -41,7 +43,7 @@ > -- input value received, or, if the upstream processor has > -- been depleted, continues with the decoupled processor @q@. -> fetch' :: a' -> Producer b' b f a -> P a' a b' b f a+> fetch' :: a' -> Producer b b' f a -> P a' a b b' f a > fetch' x q = consume x deliver q > -- | @emit y@ represents a singleton stream processor that@@ -49,7 +51,7 @@ > -- 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@@ -58,21 +60,71 @@ > -- 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' :: 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 > -- 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 ()) -> -- | @liftP@ lifts the value of a base functor into a stream processor.+> -- | @qlift@ lifts the value of a base functor into a stream processor. -> liftP :: Functor f => f r -> P a' a b' b f r-> liftP = enclose . fmap deliver+> 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+> -- uses a pure function @f@ to convert every input value into+> -- an output, and @f@ to convert each downstream response value+> -- 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 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) -> P () a b b' f ()+> qpure_ f = cloop+> where+> cloop = consume () ploop (deliver ())+> ploop x = produce (f x) (const cloop) (deliver ())++> -- | A pull-based identity processor, equivalent to 'qpure id id'.++> qid :: b -> P b a a b f ()+> qid = cloop+> where+> cloop z = consume z ploop (deliver ())+> ploop x = produce x cloop (deliver ())++> -- | A pull-based list flattening processor, delivering the list+> -- of inputs that could not be produced and a list of responses+> -- that could not be consumed.++> qconcat :: [b] -> P [b] [a] a b f ([a], [b])+> qconcat = cloop+> where+> cloop ys = consume ys (ploop []) (deliver ([], []))+> 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_ :: P () [a] a b 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.@@ -92,7 +144,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@@ -114,7 +166,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)
src/Control/Quiver/Internal.lhs view
@@ -37,7 +37,7 @@ 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@@ -48,8 +48,11 @@ > -- next element of the input stream. > -- > -- * @a@ is the type of the actual information being consumed-> -- by this stream processor (i.e., its input stream.)+> -- 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 > -- stream produced by this stream processor.@@ -69,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@@ -78,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@@ -87,12 +90,12 @@ > -- (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@.@@ -102,36 +105,36 @@ > -- | 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) -> 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)@@ -148,7 +151,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@@ -158,19 +161,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 @@ -182,7 +185,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)@@ -193,7 +196,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)