Как я могу определить размер шрифта в Haskell? - PullRequest
13 голосов
/ 29 февраля 2012

Предположим, я создал тип следующим образом:

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

Я вижу, что он имеет размер 2 * 4 байта и где-то это константа.

Единственная проблема состоит в том, что, как только я добавлю поле к типу, мне придется помнить, чтобы обновить мою константу.

Есть ли какая-нибудь функция, которая предоставит мне размер данного типа, например, t -> Int?

Функция, которая приближается к тому, что я хочу, это

gsize :: Data a => a -> Int

внутри модуля Data.Generics.Schemes, но я не хочу, чтобы мой тип был экземпляром Data.

Есть ли более общее решение?

Конечно, я ищу функцию, которая работает со статическим типом, например, я не хочу передавать экземпляр, а сам тип.

Ответы [ 2 ]

11 голосов
/ 29 февраля 2012

Это действительно зависит от того, как вы превращаете это в байты.

Как Word32, фиксированного размера не существует. То, что вы видите как Word32, может быть неприменяемым закрытием, занимающим сотни мегабайт пространства. Или это может быть простой коробочный тип (который будет больше, чем 4 байта). Или это может быть какой-то встроенный теговый тип (в этом случае это зависит от платформы). Или это может быть исключено (в этом случае не существует ).

Единственный раз, когда вы действительно можете сказать, какого размера что-то подобное, это когда вы конвертируете в двоичный файл. Если вы делаете это для взаимодействия с FFI, вы можете использовать sizeOf член Foreign.Storable. Конечно, вам нужно написать экземпляр Storable для вашего типа, если вы хотите просто применить sizeOf непосредственно к нему. Если вы сериализуете через Data.Binary ... ну, просто сериализуйте это, правда. Обычно вам не нужно заранее знать фактический размер (и если вы делаете для заголовка размера, просто сериализуйте тело, на которое вы рассчитываете размер, во временную ленивую строку, затем возьмите размер, затем запишите размер и темп байтовой строки).

2 голосов
/ 13 апреля 2017

bitSizeMaybe и finiteBitSize из Data.Bits обеспечивают размер в битах.Они заменяют bitSize из того же модуля.

finiteBitSize :: b -> Int

Возвращает количество бит в типе аргумента.Фактическое значение аргумента игнорируется.

finiteBitSize = bitSize
bitSizeMaybe = Just . finiteBitSize

Пример использования:

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