Haskell equivalente de "Construct" de Python
Pregunta
Construct es un DSL implementado en Python utilizado para describir estructuras de datos (binario y textual). Una vez que tenga la estructura de datos descrita, construcción puede analizarla y construirla por usted. Lo cual es bueno (" DRY " ;, " Declarative " ;, " Denotational-Semantics " ...)
Ejemplo de uso:
# code from construct.formats.graphics.png
itxt_info = Struct("itxt_info",
CString("keyword"),
UBInt8("compression_flag"),
compression_method,
CString("language_tag"),
CString("translated_keyword"),
OnDemand(
Field("text",
lambda ctx: ctx._.length - (len(ctx.keyword) +
len(ctx.language_tag) + len(ctx.translated_keyword) + 5),
),
),
)
Necesito una herramienta para Haskell y Me pregunto si existe algo así.
Sé de:
- Data.Binary: el usuario implementa el análisis y la construcción por separado
- Parsec: ¿Solo para analizar? ¿Solo para texto?
¿Supongo que uno debe usar Template Haskell para lograr esto?
Solución 3
Actualmente (afaik) no hay equivalente a Construir en Haskell.
Se puede implementar uno usando Template Haskell.
Otros consejos
Diría que depende de lo que quieras hacer y si necesitas cumplir con cualquier formato existente.
Data.Binary (¡sorpresa!) lo ayudará con datos binarios, tanto de lectura como de lectura escritura. Puede escribir el código para leer / escribir usted mismo, o dejar ir los detalles y generar el código requerido para sus estructuras de datos utilizando algunas herramientas adicionales como DrIFT o Derive . DrIFT funciona como un preprocesador, mientras que Derive puede funcionar como un preprocesador y con TemplateHaskell.
Parsec solo lo ayudará a analizar el texto. Sin datos binarios (tan fácilmente), y sin escritura. El trabajo se realiza con String
s regulares. Hay ByteString
equivalentes en el pirateo.
Para su ejemplo anterior, usaría Data.Binary y escribiría put
/ get
ers yo mismo.
Eche un vistazo a la categoría de analizador en el pirateo para más opciones.
No sé nada sobre Python o Construct, por lo que probablemente esto no sea lo que está buscando, pero para estructuras de datos simples siempre puede derivar leer:
data Test a = I Int | S a deriving (Read,Show)
Ahora, para la expresión
read "S 123" :: Test Double
GHCi emitirá: S 123.0
Para cualquier cosa más compleja, puede hacer una instancia de Leer usando Parsec.