Generally, you need to compose a Producer
with a Consumer
in order to get an Effect
which can be run by runEffect
. That's not what you've got here, but fortunately, there are more ways to eliminate a Proxy
than just runEffect
.
Taking stock of what we have, this composition ends up with a Producer
.
pipe :: Producer a IO ()
pipe = (undefined :: Producer ByteString IO ()) >-> (undefined :: Pipe ByteString a IO ())
The Pipes.Prelude
module contains many other ways to eliminate Producers
like Pipes.Prelude.last
last :: Monad m => Producer a m () -> m (Maybe a)
Probably the most general way to get a
s out is to use Pipes.Prelude.fold
fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Producer a m () -> m b
which is like runEffect
except it reduces Producers
to their underlying Monad
. Since that's what we have it'll work great. Here's how we can implement Pipes.Prelude.head
slowHead = fold (\res a -> res <> First (Just a)) mempty getFirst
Though it's worth noting that slowHead
consumes the entire Producer
(and thus performs all of the needed effects) while Pipes.Prelude.head
performs just the first one. It's much lazier!