10

で直接Put使用するよりもモナドが提供するものについて混乱しています。Dealing with Binary dataのBinary Generationセクションを読みました。BuilderData.BinaryPut

Data.Binary.Put

Put モナド。遅延バイト文字列を効率的に構築するためのモナド。

type Put = PutM ()

Put は単に Builder を Writer モナドにリフトし、() に適用します。

Data.Binary.Builder

遅延バイト文字列の効率的な構築。


Writerに適用されるモナドのポイントは何()ですか?

それPutは(型の同義語である)モナドであるのに対し、そうではないことがわかりますが、なぜ必要なのかはよくわかり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

これにより、簡単に 24 ビットに変換putできます。Colour Word8しかし、ヘッダーも追加する必要があり、どうすればよいかわかりません。

Builder舞台裏に隠されることを意図していますか、それとも依存していますか? このクラスは、Binaryデータのシリアル化 (非) 化のみを目的としていますか、それともすべてのバイナリ生成を目的としていますか?

4

3 に答える 3

11

まず、概念の違いに注意してください。ビルダーはバイト文字列ストリームを効率的に構築するためのものであり、PutMモナドは実際にはシリアル化のためのものです。したがって、最初に自問する必要があるのは、実際にシリアル化を行っているかどうかです (これに答えるには、意味のある正反対の操作である逆シリアル化があるかどうかを自問してください)。

一般的に、私はBuilderそれが提供する便利さのために行きます. ただし、バイナリBuilderパッケージからではなく、実際にはblaze-builderパッケージからです。これはモノイドであり、定義済みの文字列ジェネレーターが多数あります。また、非常に構成可能です。最後に、非常に高速で、実際に微調整できます。

最後になりましたが、速度、利便性、および洗練されたコードが本当に必要な場合は、これを、conduitenumerator、またはpipesなどのさまざまなストリーム プロセッサ ライブラリのいずれかと組み合わせる必要があります。

于 2012-07-16T21:55:10.493 に答える
10

Putそれはモナドであるのに対し、そうではないことはわかりますが、なぜ必要になるのかはわかりBuilderません。Put

正確にPutMは、Monadです。利便性とエラーの機会を減らすために必要です。多くの場合、モナディックまたはアプリケーションスタイルでコードを記述する方が、すべての一時的なものを明示的に持ち運ぶよりもはるかに便利です。インスタンスで配管を行うことで、関数の途中でMonad誤って間違ったコードを使用することはできません。Builder

PutMを使用するだけですべてを行うことができますBuilderが、通常はコードを作成する方が手間がかかります。

しかし、それから私もヘッダーに取り組む必要があり、それをどのように行うべきかわかりません。

PPMの形式がわからないので、ヘッダーの作成方法がわかりません。しかし、それを構築した後、あなたは単にそれを使用するputByteStringputLazyByteString、それに取り組むことができます。

于 2012-07-16T21:15:38.837 に答える
3

これがどの程度正確かはわかりませんが、私の理解では、Putご覧のように の表現は主に do 表記法を乱用しているため、次のようなコードを書くことができます。

putThing :: Thing -> Put
putThing (Thing thing1 thing2) = do
  putThing1 thing1
  putThing2 thing2

の「本質」は使用していませんがMonad(特に、何かの結果をバインドすることはありません)、連結のための便利でクリーンな構文が得られます。ただし、純粋なモノイドの代替手段に対する審美的な利点は次のとおりです。

putThing :: Thing -> Builder
putThing (Thing thing1 thing2) = mconcat [
  putThing thing1,
  putThing thing2]

私の見解では、かなり最小限です。

(Get対照的に、 は純粋モナドであり、明確な方法でそうであることから利益を得ることに注意してください)。

于 2012-07-31T16:01:06.447 に答える