2012-02-29 7 views
12

は、次のように私はタイプを作成したと想定しますHaskellで型のサイズを調べるにはどうしたらいいですか?

data RequestAck = 
     RequestAck { ackOK :: Word32, ackMsgCode :: Word32 } 

私はそれは大きな2 * 4バイトであることを確認し、一定のどこかにいることを行うことができます。

唯一の問題は、タイプにフィールドを追加すると、定数を更新することを忘れてしまいます。

特定のタイプのサイズを提供する機能がありますか?たとえばt -> Int?私が欲しいものに近づく

機能はData.Generics.Schemesモジュール内部の

gsize :: Data a => a -> Int

ですが、私は私のタイプDataのインスタンスを作成する必要がありますする必要はありません。

より一般的な解決策はありますか?

確かに、静的型で動作する関数を探しています。たとえば、インスタンスを渡すのではなく、型自体を渡すことができます。

+2

ヒント:それは大きな2つの* 4バイトではありません。フィールドはボックス化されています。 –

+1

良い点。私の場合、私は単語を引き出し、2 * 4バイトの長さに終わるバイトテストに変換します。だから、振り返ってみると、そのタイプのサイズを得ることはそれのために私には意味をなさないでしょう。 –

+2

"Haskellデータ型のメモリフットプリント":http:// stackoverflow。com/questions/3254758/memory-footprint-of-haskell-data-types、「GHCのデータ表現のメモリ表現の見方」http://stackoverflow.com/questions/6574444/how-to-find-out -ghcs-memory-data-representations-of-data-types –

答えて

11

これは、これをどのようにバイトに変換するかによって大きく異なります。

Word32として、固定サイズはありません。 Word32と表示されているものは、数百MBのスペースを占める未適用のクロージャです。または、それは単純なボックス型(4バイトより大きい)である可能性があります。または、それはある種のインラインタグ付きタイプ(その場合はプラットフォームに依存します)でもかまいません。または、それを省略することもできます(その場合はは存在しません))。

実際にこのようなサイズが何かと言うことができるのは、バイナリに変換するときだけです。 FFIとのインターフェイスをとる場合は、the sizeOf member of Foreign.Storableを使用できます。もちろん、sizeOfを直接適用する場合は、そのタイプのStorableインスタンスを記述する必要があります。あなたがData.Binaryを介してシリアル化しているのであれば、実際にはシリアル化してください。あなたは通常、実際のサイズを事前に知る必要はありません(そして、サイズヘッダの場合は、サイズを数えているボディを一時的な遅延バイトストリングにシリアル化してから、サイズを取り出し、サイズと温度を書きますbytestring)。

+2

実際のByteStringサイズを測定する提案によると、私はサーバ/クライアントプロトコルを変更して、各バイナリメッセージの前にByteStringのサイズを含む単語を付けます(私は事前に測定しています)。その洞察に感謝します。 –

1

bitSizeMaybeおよびfiniteBitSizeData.Bitsは、ビット単位のサイズを提供します。それらは同じモジュールからbitSizeに取って代わります。

finiteBitSize :: b -> Int 

戻り引数の型のビット数。引数の実際の 値は無視されます。

finiteBitSize = bitSize 
bitSizeMaybe = Just . finiteBitSize 

使用例:

> import Data.Bits 
> finiteBitSize (42 :: Int) 
64 
関連する問題