purescript-contrib / purescript-aff

An asynchronous effect monad for PureScript
https://pursuit.purescript.org/packages/purescript-aff
Apache License 2.0
285 stars 66 forks source link

Add AStream abstraction for asynchronous, effectful streams #14

Closed jdegoes closed 9 years ago

jdegoes commented 9 years ago

Option 1: ListT (Aff eff) a

Just use ListT:

newtype AStream eff a = AStream (ListT (Aff eff) a)

One can hide the monadic instance with a newtype, or one can expose it.

In any case, one needs an "emit along the way" combinator, something like this (or Halogen's andThen):

yield :: forall eff a. Aff eff a -> (a -> AStream eff a) -> AStream eff a

yield (Ajax.get baseUrl) (\resp -> yield Ajax.get resp.destUrl (\_ ... ))

Option 1: Stream with 2 type params

data AStream eff o r = Done r | More (Aff eff { output :: o, next :: AStream eff o r })

This is basically the simplest (possibly finite) stream which allows you to emit values of one type and (monadically) return a value of another type. It supports all the usual instances on a.

The bad thing about this representation is that you cannot map, et al, on the output of the stream, because all such instances apply to the terminal value of the stream -- which is very surprising for a stream abstraction. :-1:

Option 3: purescript-channels / purescript-streams

One can always defer to these libraries, even including a helper based on them here.

jdegoes commented 9 years ago

Most likely this will be Applicative and be implemented using ListT (Par eff) a.