Combining a Pipe and Producer

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Combining a Pipe and Producer

Merijn Verstraaten
Hi,

In my current code I have a "myPipe :: Pipe Foo Bar m r" (that consumes any number of inputs) and a "myProd :: Producer Bar m r" (that produces a finite number of outputs) that I want to combine so that the Producer runs after the pipe exhausts all it's input. Given an "inputProducer :: Producer Foo m r" I can write "(inputProducer >-> myPipe) >> myProd" to get the desired effect, but this is horrible thing for users of my code to have to write.

Is there any way I can achieve this reasonably nicely? Ideally I'd like some way to combine my pipe and producer into a single "Pipe Foo Bar m r" in various ways (like returning my producer from the pipe and calling join), but since the pipe consumes any number of inputs that just results in my producer never running. Any suggestions?

Cheers,
Merijn

--



Reply | Threaded
Open this post in threaded view
|

Re: Combining a Pipe and Producer

Dan Burton
I don't believe detecting upstream termination is possible with pipes alone.


Or you can try conduit with await, which returns Nothing if the upstream source has terminated
https://www.stackage.org/haddock/lts-9.5/conduit-1.2.12/Data-Conduit.html#v:await

Contrast with the await from pipes, which does not grant the opportunity to recover from upstream termination
https://www.stackage.org/haddock/lts-9.5/pipes-4.3.4/Pipes.html#v:await

If you don't mind stepping the producer yourself, you can try using next from pipes
https://www.stackage.org/haddock/lts-9.5/pipes-4.3.4/Pipes.html#v:next

-- Dan Burton

On Wed, Sep 20, 2017 at 8:21 AM, Merijn Verstraaten <[hidden email]> wrote:
Hi,

In my current code I have a "myPipe :: Pipe Foo Bar m r" (that consumes any number of inputs) and a "myProd :: Producer Bar m r" (that produces a finite number of outputs) that I want to combine so that the Producer runs after the pipe exhausts all it's input. Given an "inputProducer :: Producer Foo m r" I can write "(inputProducer >-> myPipe) >> myProd" to get the desired effect, but this is horrible thing for users of my code to have to write.

Is there any way I can achieve this reasonably nicely? Ideally I'd like some way to combine my pipe and producer into a single "Pipe Foo Bar m r" in various ways (like returning my producer from the pipe and calling join), but since the pipe consumes any number of inputs that just results in my producer never running. Any suggestions?

Cheers,
Merijn

--

--
Reply | Threaded
Open this post in threaded view
|

Re: Combining a Pipe and Producer

Daniel Díaz Carrete
In reply to this post by Merijn Verstraaten
I sometimes write libraries that expose Producer -> Producer functions like that.

Perhaps you could provide some helper functions that manipulated Producer -> Producer functions and hid the >-> and even the >>.

On Wednesday, September 20, 2017 at 5:21:21 PM UTC+2, Merijn Verstraaten wrote:
Hi,

Given an "inputProducer :: Producer Foo m r" I can write "(inputProducer >-> myPipe) >> myProd" to get the desired effect, but this is horrible thing for users of my code to have to write. 

--
Reply | Threaded
Open this post in threaded view
|

Re: Combining a Pipe and Producer

Dan Burton
That's basically what pipes-parse is.

e.g. the Parser monad is
type Parser a m r = forall x. StateT (Producer a m x) m r


It is a State monad transformer where the state is a Producer, so operations in this monad can "alter" the Producer as they go along. So it's basically manipulation of Producer -> (a, Producer) functions (the state monad), except as a monad transformer it additionally allows for interleaving side effects in the "base monad" m.

-- Dan Burton

On Fri, Sep 22, 2017 at 9:04 AM, Daniel Díaz <[hidden email]> wrote:
I sometimes write libraries that expose Producer -> Producer functions like that.

Perhaps you could provide some helper functions that manipulated Producer -> Producer functions and hid the >-> and even the >>.

On Wednesday, September 20, 2017 at 5:21:21 PM UTC+2, Merijn Verstraaten wrote:
Hi,

Given an "inputProducer :: Producer Foo m r" I can write "(inputProducer >-> myPipe) >> myProd" to get the desired effect, but this is horrible thing for users of my code to have to write. 

--

--