k0001 / pipes-binary

Encode and decode binary streams using the pipes and binary libraries.
Other
7 stars 12 forks source link

encodeMany is missing #2

Closed kvanbere closed 11 years ago

kvanbere commented 11 years ago

I've found myself desiring a version of encode which hides the argument in the Proxy, that is, in the same way decodeMany takes a Producer, encodeMany would take a Consumer and repeatedly encode, sending the result downstream.

k0001 commented 11 years ago

The reason encodeMany is not provided is because encode is flexible and straightforward to use for various purposes, including the one you ask about.

Taking a Consumer as an argument is not really idiomatic within Pipes, there are better ways to use input from upstream. For example, you can use for and cat together with a “loop body” to build a new Proxy consuming input from upstream and possibly producing more output.

>>> :t encode
encode
  :: (Monad m, Binary b) => b -> Producer' ByteString m ()

>>> :t for
for
  :: Monad m =>
     Proxy x' x b' b m a'
     -> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'

>>> :t cat
cat :: Monad m => Pipe a a m r

>>> :t for cat
for cat
  :: Monad m => (b -> Proxy () b c' c m ()) -> Proxy () b c' c m a'

>>> :t for cat encode
for cat encode
  :: (Monad m, Binary b) => Proxy () b () ByteString m a'
  -- simplified type: 
  --   :: (Monad m, Binary b) => Pipe b ByteString m a' 

>>> runEffect $ each [1,2] >-> for cat encode >-> P.print
"\NUL\NUL\NUL\NUL\SOH"
"\NUL\NUL\NUL\NUL\STX"

Or you can use (~>) to compose those “loop bodies” directly:

>>> :t (~>)
(~>)
  :: Monad m =>
     (a -> Proxy x' x b' b m a')
     -> (b -> Proxy x' x c' c m b') -> a -> Proxy x' x c' c m a'

>>> :t (encode ~>)
(encode ~>)
  :: (Monad m, Binary a) =>
     (ByteString -> Proxy x' x c' c m ()) -> a -> Proxy x' x c' c m ()

>>> :t encode ~> lift . print
encode ~> lift . print :: Binary a => a -> Proxy x' x c' c IO ()

>>> runEffect $ for (each [1,2]) $ encode ~> lift . print
"\NUL\NUL\NUL\NUL\SOH"
"\NUL\NUL\NUL\NUL\STX"

Does this help?

kvanbere commented 11 years ago

Hi,

Thanks for that. Makes a lot of sense now.

It would be nice if you were to include a brief version of this explanation in the documentation for pipes-binary somewhere.

Regards.

k0001 commented 11 years ago

The reason I didn't mention this in the documentation is because Pipes.Tutorial talks about a lot about it. But you are right, adding an example or two to the documentation wouldn't hurt. I'll add that, thanks.