Как я могу определить размер шрифта в Haskell?
Предположим, я создал тип следующим образом:
data RequestAck =
RequestAck { ackOK :: Word32, ackMsgCode :: Word32 }
Я вижу, что он имеет размер 2 * 4 байта и где-то это константа.
Единственная проблема состоит в том, что, как только я добавлю поле к типу, мне придется помнить, чтобы обновить мою константу.
Есть ли функция, которая предоставит мне размер данного типа, например, t -> Int
?
Функция, которая приближается к тому, что я хочу,
gsize :: Data a => a -> Int
внутри модуля Data.Generics.Schemes, но я не хочу делать мой тип экземпляром Data
,
Есть ли более общее решение?
Конечно, я ищу функцию, которая работает со статическим типом, например, я не хочу передавать экземпляр, а сам тип.
2 ответа
Это действительно зависит от того, как вы превращаете это в байты.
Как Word32
, нет фиксированного размера. Что вы видите как Word32
может быть неприменимым закрытием, занимающим сотни мегабайт пространства. Или это может быть простой коробочный тип (который будет больше, чем 4 байта). Или это может быть какой-то встроенный теговый тип (в этом случае это зависит от платформы). Или это может быть исключено (в этом случае его не существует).
Единственный раз, когда вы действительно можете сказать, какого размера что-то вроде этого, это когда вы конвертируете в двоичный файл. Если вы делаете это для взаимодействия с FFI, вы можете использовать sizeOf
членForeign.Storable
, Конечно, вам нужно написать экземпляр Storable для вашего типа, если вы хотите просто применить sizeOf
прямо к нему. Если вы сериализуете через Data.Binary... ну, просто сериализуйте это, правда. Обычно вам не нужно заранее знать фактический размер (и если вы делаете для заголовка размера, просто сериализуйте тело, на которое вы рассчитываете размер, во временную ленивую строку, затем возьмите размер, затем запишите размер и темп байтовой строки).
bitSizeMaybe
а также finiteBitSize
из Data.Bits предоставляют размер в битах. Они вытесняют bitSize
из того же модуля.
finiteBitSize :: b -> Int
Вернуть количество бит в типе аргумента. Фактическое значение аргумента игнорируется.
finiteBitSize = bitSize
bitSizeMaybe = Just . finiteBitSize
Пример использования:
> import Data.Bits
> finiteBitSize (42 :: Int)
64