
Is there a way to get the underlying Builder of a 'put' of a Binary instance? How does the Char instance of Binary serialize?

On Fri, 2009-01-23 at 15:34 +0100, Henning Thielemann wrote:
Is there a way to get the underlying Builder of a 'put' of a Binary instance?
The binary package exposes the Data.Binary.Builder module so you can use the Builder monoid directly. There is no need to go via the Put wrapper. There is no way to get at the 'current' state of the underlying Builder value. In principle, it could provide the normal writer monad access functions. What is the use case? Is there anything you can do with direct access you cannot do with Put operations? If you want to inspect the data already written then I suggest you do not. It would involve running the whole thing twice (because internally it's something like a difference list).
How does the Char instance of Binary serialize?
http://hackage.haskell.org/packages/archive/binary/0.4.4/doc/html/src/Data-B... -- Char is serialised as UTF-8 instance Binary Char where ... Duncan

On Fri, Jan 23, 2009 at 08:03:52PM +0000, Duncan Coutts wrote:
On Fri, 2009-01-23 at 15:34 +0100, Henning Thielemann wrote:
Is there a way to get the underlying Builder of a 'put' of a Binary instance?
The binary package exposes the Data.Binary.Builder module so you can use the Builder monoid directly. There is no need to go via the Put wrapper.
There is no way to get at the 'current' state of the underlying Builder value. In principle, it could provide the normal writer monad access functions. What is the use case?
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.

Duncan Coutts schrieb:
On Fri, 2009-01-23 at 15:34 +0100, Henning Thielemann wrote:
Is there a way to get the underlying Builder of a 'put' of a Binary instance?
The binary package exposes the Data.Binary.Builder module so you can use the Builder monoid directly. There is no need to go via the Put wrapper.
I know, but the Binary class provides only a 'put' method in the 'PutM' monad. I can wrap Put in a newtype with Monoid instance in order to get what I want, but I hoped it would be simpler.
How does the Char instance of Binary serialize?
http://hackage.haskell.org/packages/archive/binary/0.4.4/doc/html/src/Data-B...
-- Char is serialised as UTF-8 instance Binary Char where ...
Since this does not appear in the documentation, this is undocumented behaviour? Just a Haddock deficiency, I know.

Here's a concrete suggestion: have Data.Binary.Put export the existing function tell :: Builder -> Put and also execPut :: PutM a -> Builder execPut = sndS . unPut

On Thu, Feb 12, 2009 at 07:28:07AM -0800, Don Stewart wrote:
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Quoting a previous message:
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.

ross:
On Thu, Feb 12, 2009 at 07:28:07AM -0800, Don Stewart wrote:
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Quoting a previous message:
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.
Sounds good. Do you just want these exposed as is? -- Don

On Thu, Feb 12, 2009 at 07:40:21AM -0800, Don Stewart wrote:
ross:
On Thu, Feb 12, 2009 at 07:28:07AM -0800, Don Stewart wrote:
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Quoting a previous message:
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.
Sounds good. Do you just want these exposed as is?
Yes, though Antoine's suggestion of exporting tell as putBuilder may be better.

ross:
On Thu, Feb 12, 2009 at 07:40:21AM -0800, Don Stewart wrote:
ross:
On Thu, Feb 12, 2009 at 07:28:07AM -0800, Don Stewart wrote:
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Quoting a previous message:
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.
Sounds good. Do you just want these exposed as is?
Yes, though Antoine's suggestion of exporting tell as putBuilder may be better.
OK. I'm preparing the 0.5 release of binary atm, so will expose these. -- Don

Don Stewart wrote:
OK. I'm preparing the 0.5 release of binary atm, so will expose these.
-- Don
Don: I had proposed (with a patch) to let the caller of runPut give a size hint so the first chunk allocated for the Lazy ByteString would not have to always be the default value (which I remember being about 32 kilo bytes). If the first allocation filled up the subsequent chunks are still the default size. My use case was for the protocol-buffers package where the serialized message sizes are both known in advance and often much much smaller than this. I have no benchmarks, but it feels wrong to have my library constantly over-allocating. Is such a feature going to be accepted into the binary package? If not then I may just copy over and patch the Put monad. (I do not use an external Get monad, the protocol-buffers package includes its own Get monad). Cheers, Chris

haskell:
Don Stewart wrote:
OK. I'm preparing the 0.5 release of binary atm, so will expose these.
-- Don
Don: I had proposed (with a patch) to let the caller of runPut give a size hint so the first chunk allocated for the Lazy ByteString would not have to always be the default value (which I remember being about 32 kilo bytes). If the first allocation filled up the subsequent chunks are still the default size.
My use case was for the protocol-buffers package where the serialized message sizes are both known in advance and often much much smaller than this. I have no benchmarks, but it feels wrong to have my library constantly over-allocating.
Is such a feature going to be accepted into the binary package? If not then I may just copy over and patch the Put monad. (I do not use an external Get monad, the protocol-buffers package includes its own Get monad).
Could you dig up the patch again?

ross:
On Thu, Feb 12, 2009 at 07:40:21AM -0800, Don Stewart wrote:
ross:
On Thu, Feb 12, 2009 at 07:28:07AM -0800, Don Stewart wrote:
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Quoting a previous message:
I imagine one might want to make a Builder for a composite object, using the Binary instances of some types. And one might want to go the other way too, defining a Binary instance using an existing Builder.
Sounds good. Do you just want these exposed as is?
Yes, though Antoine's suggestion of exporting tell as putBuilder may be better.
Is this what you're looking for?
Thu Feb 12 09:47:34 PST 2009 Don Stewart

On Thu, Feb 12, 2009 at 9:28 AM, Don Stewart
ross:
Here's a concrete suggestion: have Data.Binary.Put export the existing function
tell :: Builder -> Put
and also
execPut :: PutM a -> Builder execPut = sndS . unPut
What's the use case?
Maybe 'tell' could be renamed to 'putBuilder', thereby not exposing the fact that the function is reaching into the guts of the abstraction. -Antoine
participants (7)
-
Antoine Latter
-
Chris Kuklewicz
-
Don Stewart
-
Duncan Coutts
-
Henning Thielemann
-
Henning Thielemann
-
Ross Paterson