Equivalente di Haskell del "Costrutto" di Python
Domanda
Construct è un DSL implementato in Python usato per descrivere strutture di dati (binarie e testuali). Una volta descritta la struttura dei dati, construct può analizzarla e crearla per te. Che è buono ("DRY", "dichiarativo", "denotazionale-semantica" ...)
Esempio di utilizzo:
# 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),
),
),
)
Ho bisogno di un simile strumento per Haskell e Mi chiedo se esista qualcosa del genere.
Conosco:
- Data.Binary: l'utente implementa l'analisi e la costruzione separatamente
- Parsec: solo per l'analisi? Solo per il testo?
Suppongo che si debba usare Template Haskell per raggiungere questo obiettivo?
Soluzione 3
Attualmente (afaik) non esiste un equivalente a Construct in Haskell.
Uno può essere implementato usando Template Haskell.
Altri suggerimenti
Direi che dipende da cosa vuoi fare e se devi conformarti a qualsiasi formato esistente.
Data.Binary ti aiuterà (a sorpresa!) con i dati binari, sia in lettura che in lettura la scrittura. Puoi scrivere il codice per leggere / scrivere te stesso o lasciar andare i dettagli e generare il codice richiesto per le tue strutture dati usando alcuni strumenti aggiuntivi come DrIFT o Derive . DrIFT funziona come preprocessore, mentre Derive può funzionare come preprocessore e con TemplateHaskell.
Parsec ti aiuterà solo con l'analisi del testo. Nessun dato binario (altrettanto facilmente) e nessuna scrittura. Il lavoro viene svolto con i normali String
. Esistono ByteString
su hackage.
Per il tuo esempio sopra, userei Data.Binary e scrivo personalmente put
/ get
.
Dai un'occhiata alla categoria parser su hackage per più opzioni.
Non so nulla di Python o Construct, quindi questo probabilmente non è quello che stai cercando, ma per semplici strutture dati puoi sempre derivare leggi:
data Test a = I Int | S a deriving (Read,Show)
Ora, per l'espressione
read "S 123" :: Test Double
GHCi emetterà: S 123.0
Per qualcosa di più complesso, puoi creare un'istanza di Read usando Parsec.