mk1*_*k12 10 monads haskell functional-programming binary-data
我对Put
monad提供的Builder
直接使用内容感到困惑Data.Binary
.我阅读了处理二进制数据的二进制生成部分,它似乎假设您应该使用Put
,但它很短并不能解释原因.
Data.Binary.Put
Put monad.一个有效构造惰性字节串的monad.
Run Code Online (Sandbox Code Playgroud)type Put = PutM ()
只需将Builder升级为Writer monad,应用于().
Data.Binary.Builder
高效构造惰性字节串.
什么是点Writer
单子应用()
?
我可以看到它Put
是(一个类型的同义词)monad而Builder
不是,但我真的不明白为什么Put
需要.
在我的例子中,我正在渲染3D场景并将每个像素写为3个字节,然后将PPM格式的标题添加到开头(之后将使用PNG).
Binary
似乎它是为了可以对二进制数据进行序列化和反序列化的类型进行实例化.这不完全是我正在做的事情,但是Binary
为我的颜色类型实例化感觉很自然
instance (Binary a) => Binary (Colour a) where
put (Colour r g b) = put r >> put g >> put b
get = Colour <$> get <*> get <*> get
Run Code Online (Sandbox Code Playgroud)
这可以很容易地put
一Colour Word8
到24位.但是接下来我还要抓住标题,我不知道该怎么做.
是Builder
隐藏在幕后,还是依赖于它?是Binary
类只对(反)序列数据,或所有二进制代的目的呢?
小智 11
首先要注意概念上的差异.构建器用于高效构建字节串流,而PutM
monad实际上用于序列化.所以你应该问自己的第一个问题是你是否真的在序列化(回答问自己是否有一个有意义且完全相反的操作 - 反序列化).
一般来说,我会选择Builder
它提供的便利.但是,不是Builder
来自二进制包,而是来自blaze-builder包.它是一个monoid并且有许多预定义的字符串生成器.它也非常易于组合.最后它非常快,实际上可以进行微调.
最后但并非最不重要的是,如果您真的想要速度,便利和优雅的代码,您将需要将其与各种流处理器库之一(如管道,枚举器或管道)相结合.
Dan*_*her 10
我可以看到这
Put
是一个单子而Builder
不是,但我真的不明白为什么Put
需要它.
确切地说,PutM
是Monad
.这是为了方便起见,并为您提供更少的错误机会.以monadic或applicative样式编写代码通常比明确地携带所有临时代码更方便,并且在Monad
实例中完成管道,您不能Builder
在函数中间意外使用错误.
你可以PutM
只使用你所做的一切Builder
,但通常编写代码的工作量更大.
但是接下来我还要抓住标题,我不知道该怎么做.
我不知道PPM格式,所以我不知道如何构造标题.但是在构建它之后,你可以简单地使用putByteString
或者putLazyByteString
解决它.