Open alang9 opened 9 years ago
Can you give an example of how you planned to use this?
My particular application is something like this:
consumerToIteratee :: (Monad m, I.Nullable a) => Consumer a m r -> I.Iteratee a m r
consumerToIteratee = go
where
go consumer = do
a <- I.getChunk
out <- lift $ runPartial $ return a >~ consumer
case out of
Left r -> return r
Right next -> go next
where I.Iteratee
is from the iteratee
package.
In this case you can use runEffect
instead of runPartial
. return a >~ consumer
will type-check as an Effect
, meaning that it's guaranteed not to have any Request
/Respond
constructors.
You can also tell that it won't have any Request
/Respond
constructors by observing that Consumer
only has Request
/Pure
/M
constructors, and then (return a >~)
eliminates all the Request
constructors.
I see. I think >~
doesn't do what I thought it did. Upon further inspection, I agree that runPartial
is not very useful, but I would like a function like feed
feed :: Monad m => a -> Consumer a m r -> m (Either r (Consumer a m r))
feed a = go
where
go c = case c of
Request () fu -> go2 (fu a)
Respond v _ -> closed v
M m -> m >>= go
Pure r -> return (Left r)
go2 c = case c of
Request _ _ -> return (Right c)
Respond v _ -> closed v
M m -> m >>= go2
Pure r -> return (Left r)
To be able to write:
consumerToIteratee :: (Monad m, I.Nullable a) => Consumer a m r -> I.Iteratee a m r
consumerToIteratee = go
where
go consumer = do
a <- I.getChunk
out <- lift $ feed a consumer
case out of
Left r -> return r
Right next -> go next
Alternately, feed
could be the following, in which case it looks dual to next
:
feed2 :: Monad m => a -> Consumer a m r -> m (Either r (a -> Consumer a m r))
feed2 a = go
where
go c = case c of
Request () fu -> go2 (fu a)
Respond v _ -> closed v
M m -> m >>= go
Pure r -> return (Left r)
go2 c = case c of
Request () fu -> return (Right fu)
Respond v _ -> closed v
M m -> m >>= go2
Pure r -> return (Left r)
I like the idea of some feed
-like function that lets you step Consumer
. Could I suggest this slight variation on the type signature you gave
feed :: Monad m => Consumer a m r -> m (Either r (a -> Consumer a m r))
Notice how you don't supply the a
directly to feed
. Instead, it may give you a (a -> Consumer a m r)
and you supply the a
to that instead.
...possible
Seems to be a useful utility function that's currently missing.