purescript-contrib / purescript-coroutines

Computations which can suspend their execution and return control to their invoker
MIT License
38 stars 11 forks source link

How to achieve something like conduit's awaitForever. #26

Open martyall opened 6 years ago

martyall commented 6 years ago

This is not really a bug, but I'm wondering how to do something / asking if it's possible with the current implementation.

Is there any way to write something like the awaitForever from Data.Conduit? This would be for a Transformer type, but I don't see how you can do anything to make a transformer except by providing a pure function. I use this all the time in other streaming libraries in haskell to make something like a Transformer that can use the underlying m on the input, but I don't really see how to do this here. Am I missing something?

I know that this library was originally inspired by Coroutine Pipelines, but it seems that there is a very important construction there which generalizes everything, namely the Transducer type which is roughly equivalent to

type Transducer i o m a = Co (Coproduct (Await (Maybe i)) (Emit o)) m a

I know it would be possible if using something like this.

martyall commented 5 years ago

So I went ahead and implemented what was in that paper here. Not sure if there is any interest in having a layer like this, but thought I would ask.

garyb commented 5 years ago

Thanks! I don't really know much about this, I should read the paper. It looks pretty neat.

martyall commented 5 years ago

Yeah, it's cool. I went ahead and implemented a few other translation functions to get back and forth to purescript-coroutines and tried to give a brief motivation in the README for why this might be useful. Also I reimplemented the examples in your tests using these translation functions.

martyall commented 5 years ago

I was recently doing some coroutine refactoring (see linked issue) and thought about this open issue. I'm just wondering, if you read the README in the transducers repo, do you understand the limitations that I'm getting at? Can they be addressed without a separate library?

safareli commented 5 years ago

purescript-coroutines basically uses this functors

type Transform i o = Compose ((->) i) (Tuple o)
type CoTransform i o = Compose (Tuple o) ((->) i)

It's nice that they are sort of dual to each other, but composing them is harder compared to composing Transduce from purescript-coroutine-transducers:

type Transduce i o = Coproduct ((->) (Maybe i)) (Tuple o)

I would propose to move Transform/CoTransform related stuff to separate sub module, and reexport it's contents from the root module (to avoid braking change).

We can then see if people would prefer to use Transduce over Transform/CoTransform and possibly remove Transform/CoTransform or move to separate lib.