2012-02-29 26 views
12

asume que creó un tipo de la siguiente manera:¿Cómo puedo determinar el tamaño de un tipo en Haskell?

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

puedo ver que es 2 * 4 bytes grande y hacer que una constante en alguna parte.

El único problema es que una vez que agregue un campo al tipo, tendré que acordarme de actualizar mi constante.

¿Existe alguna función que me brinde el tamaño de un tipo determinado, por ejemplo, t -> Int?

La función que se acerca a lo que yo quiero es

gsize :: Data a => a -> Int

el interior del módulo Data.Generics.Schemes, pero no quiero tener que hacer mi tipo de una instancia de Data.

¿Existe una solución más genérica?

Para estar seguro, estoy buscando una función que opere en el tipo estático, por ejemplo, no quiero pasar una instancia, sino el tipo en sí.

+2

indirecta: no es de 2 * 4 bytes grande. Los campos están enmarcados. –

+1

Buen punto. En mi caso, saco las palabras y las convierto en una cadena de bytes que termina siendo de 2 * 4 bytes de longitud. Así que, en retrospectiva, obtener tamaño del tipo no tendría mucho sentido para mí debido a eso. –

+2

"Huella de memoria de los tipos de datos Haskell": http: // stackoverflow.com/questions/3254758/memory-footprint-of-haskell-data-types, también "Cómo descubrir las representaciones de memoria de tipos de datos de GHC" http://stackoverflow.com/questions/6574444/how-to-find-out -ghcs-memory-representations-of-data-types –

Respuesta

11

Esto realmente depende de cómo lo está convirtiendo en bytes.

Como Word32, no hay un tamaño fijo. Lo que ve como Word32 podría ser un cierre no aplicado que ocupe cientos de megabytes de espacio. O podría ser un tipo de caja simple (que sería más grande que 4 bytes). O podría ser algún tipo de tipo etiquetado en línea (en cuyo caso depende de la plataforma). O podría ser eliminado (en cuyo caso no existe).

El único momento en el que realmente se puede decir qué tamaño es esto es cuando se convierte en binario. Si está haciendo esto para interactuar con el FFI, puede usar the sizeOf member of Foreign.Storable. Por supuesto, debe escribir una instancia Almacenable para su tipo si desea simplemente aplicar sizeOf directamente a ella. Si estás serializando a través de Data.Binary ... bueno, solo serializa la cosa, realmente. Por lo general, no necesita saber el tamaño real de antemano (y si lo hace para un encabezado de tamaño, simplemente serialice el cuerpo del que está contando el tamaño en una cadena de bytes temporal, luego tome el tamaño, luego escriba el tamaño y la temperatura bytestring).

+2

De acuerdo con su sugerencia de medir el tamaño actual de ByteString, cambié mi protocolo de servidor/cliente para prefijar cada mensaje binario con una palabra que contiene el tamaño de ByteString que sigue (que mido de antemano). Gracias por esa idea. –

1

bitSizeMaybe y finiteBitSize de Data.Bits proporcionan el tamaño en bits. Reemplazan bitSize del mismo módulo.

finiteBitSize :: b -> Int 

devolver el número de bits en el tipo del argumento. El valor real del argumento se ignora.

finiteBitSize = bitSize 
bitSizeMaybe = Just . finiteBitSize 

Ejemplo de uso:

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