I'm confused as to what the Put
monad offers over using Builder
directly, in Data.Binary
. I read the Binary Generation section of Dealing with Binary data, and it seems to assume that you should use Put
, but it's pretty short doesn't explain why.
Data.Binary.Put
The Put monad. A monad for efficiently constructing lazy bytestrings.
type Put = PutM ()
Put merely lifts Builder into a Writer monad, applied to ().
Data.Binary.Builder
Efficient construction of lazy byte strings.
What is the point of a Writer
monad applied to ()
?
I can see that Put
is (a type synonym to) a monad whereas Builder
is not, but I don't really get why Put
would be needed.
In my case, I'm rendering a 3D scene and writing each pixel as a 3 bytes, and then adding on the PPM format's header to the beginning (will use PNG later).
Binary
seems like it is meant to be instantiated for types that can be serialized and deserialized to and from binary data. This isn't exactly what I'm doing, but it felt natural to instantiate Binary
for my colour type
instance (Binary a) => Binary (Colour a) where
put (Colour r g b) = put r >> put g >> put b
get = Colour <$> get <*> get <*> get
This makes it easy to put
a Colour Word8
into 24 bits. But then I also have to tack on the header, and I'm not sure how I should do that.
Is Builder
meant to be hidden behind the scenes, or does it depend? Is the Binary
class only for (de)serializing data, or for all binary generation purposes?
Binary
class and its methodsGet
andPut
are essentially for serializing and de-serializing Haskell structures. If you are working with a existing binary format it is better (in my opinion, of course) to avoid the Binary class and instead use the explicit functions likeputWord8
,putWord32le
, etc. – BondiePut
, and makes sense semantically too, but I don't know if I should usePut
for everything or not. – Hesson