Stiamo implementando una libreria di compressione matriciale basata su una sintassi grammaticale bidimensionale modificata. Ora abbiamo due approcci per i nostri tipi di dati, uno dei quali sarà migliore in caso di utilizzo della memoria? (vogliamo comprimere qualcosa;)).
Le grammatiche contengono Nonerminali con esattamente 4 Productions o un Terminale sul lato destro. Avremo bisogno dei nomi delle Productions per i controlli di uguaglianza e la minimizzazione della grammatica.
Il primo:
-- | Type synonym for non-terminal symbols
type NonTerminal = String
-- | Data type for the right hand side of a production
data RightHandSide = DownStep NonTerminal NonTerminal NonTerminal NonTerminal | Terminal Int
-- | Data type for a set of productions
type ProductionMap = Map NonTerminal RightHandSide
data MatrixGrammar = MatrixGrammar {
-- the start symbol
startSymbol :: NonTerminal,
-- productions
productions :: ProductionMap
}
Qui i nostri dati RightHandSide salvano solo i nomi di stringhe per determinare le prossime produzioni e ciò che non sappiamo qui è come Haskell salva queste stringhe. Ad esempio la matrice [[0, 0], [0, 0]] ha 2 produzioni:
a = Terminal 0
aString = "A"
b = DownStep aString aString aString aString
bString = "B"
productions = Map.FromList [(aString, a), (bString, b)]
Quindi la domanda qui è quanto spesso la stringa "A" è veramente salvata? Una volta in aString, 4 volte in b e una volta nelle produzioni o solo una volta in aString e gli altri hanno solo riferimenti "più economici"?
The Second:
data Production = NonTerminal String Production Production Production Production
| Terminal String Int
type ProductionMap = Map String Production
qui il termine "Terminale" è un po 'fuorviante perché in realtà è la produzione che ha un terminale come lato destro. La stessa matrice:
a = Terminal "A" 0
b = NonTerminal "B" a a a a
productions = Map.fromList [("A", a), ("B", b)]
e la domanda simile: quanto spesso la produzione è salvata internamente da Haskell? Forse lasceremo cadere i nomi all'interno delle produzioni se non ne abbiamo bisogno, ma al momento non siamo sicuri di questo.
Quindi diciamo che abbiamo una grammatica con circa 1000 produzioni. Quale approccio consumerà meno memoria?
Finalmente una domanda sui numeri interi in Haskell: attualmente stiamo pianificando di avere un nome come stringhe. Ma potremmo facilmente passare ai nomi interi perché con 1000 produzioni avremo nomi con più di 4 caratteri (che presumo sia 32 bit?). Come fa Haskell a gestirlo. Int è sempre 32 bit e Integer alloca la memoria di cui ha realmente bisogno?
Ho letto anche questo: Test di creazione del valore / riferimento Haskell semantica - ma non riesco a capire cosa significhi esattamente per noi - Sono più un imperativo figlio di java che un buon programmatore funzionale: P