如何确定Haskell中类型的大小?

时间:2012-02-29 02:32:35

标签: haskell types byte

假设我创建了一个类型如下:

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

我可以看到它是2 * 4字节大,并使其在某处保持不变。

唯一的问题是,一旦我向该类型添加了一个字段,我就必须记得更新我的常量。

是否有一个功能可以为我提供给定类型的大小,例如t -> Int

接近我想要的功能是

gsize :: Data a => a -> Int

在Data.Generics.Schemes模块中,但我不想让我的类型成为Data的实例。

那里有更通用的解决方案吗?

可以肯定的是,我正在寻找一个对静态类型进行操作的函数,例如,我不想传递实例,而是传递类型本身。

2 个答案:

答案 0 :(得分:11)

这实际上取决于你如何将其变成字节。

作为Word32,没有固定的尺寸。你所看到的Word32可能是一个未应用的闭包,占用了数百兆的空间。或者它可以是一个简单的盒装类型(大于4个字节)。或者它可能是某种内联标记类型(在这种情况下,它取决于平台)。或者可以省略(在这种情况下不存在)。

当你真正说出这样的大小时,唯一的一次是当你转换成二进制时。如果您这样做是为了与FFI连接,您可以使用the sizeOf member of Foreign.Storable。当然,如果您想直接应用sizeOf,则需要为您的类型编写一个可存储实例。如果你是通过Data.Binary进行序列化......那么,只需序列化这个东西,真的。你通常不需要事先知道实际的大小(如果你做一个大小的标题,只需序列化你正在计算的大小为一个临时的懒字节字符串,然后取大小,然后写大小和临时字节字符串)。

答案 1 :(得分:2)

来自Data.Bits

bitSizeMaybefiniteBitSize提供了位大小。他们从同一模块中取代bitSize

finiteBitSize :: b -> Int
  

返回参数类型中的位数。实际上   参数的值被忽略。

finiteBitSize = bitSize
bitSizeMaybe = Just . finiteBitSize

使用示例:

> import Data.Bits
> finiteBitSize (42 :: Int)
64