Stiamo implementando una libreria di compressione matrice basata su una sintassi grammaticale bidimensionale modificata. Ora abbiamo due approcci per i nostri tipi di dati: quale sarà meglio in caso di utilizzo della memoria? (vogliamo comprimere qualcosa;)).
Le grammatiche contengono non terminali con esattamente 4 produzioni o un terminale sul lato destro. Avremo bisogno dei nomi di Productions per controlli di uguaglianza e minimizzazione grammaticale.
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 String per determinare le produzioni successive, 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 viene salvata la stringa "A"? Una volta in aString, 4 volte in be una volta in produzioni o solo una volta in aString e gli altri hanno solo riferimenti "più economici"?
Il secondo:
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 viene salvata internamente da Haskell? Probabilmente lasceremo cadere i nomi all'interno delle produzioni se non ne avremo bisogno, ma non siamo sicuri in questo momento.
Diciamo quindi che abbiamo una grammatica con circa 1000 produzioni. Quale approccio consumerà meno memoria?
Finalmente una domanda sugli interi in Haskell: al momento stiamo pensando di avere un nome come stringhe. Ma potremmo facilmente passare a nomi interi perché con 1000 produzioni avremo nomi con più di 4 caratteri (che presumo sia a 32 bit?). Come gestisce Haskell. Un Int è sempre a 32 bit e Integer alloca la memoria di cui ha davvero bisogno?
Ho anche letto questo: Deviante test del valore / semantica di riferimento di Haskell - ma non riesco a capire cosa significhi esattamente per noi - Sono più un bambino imperativo di Java che un buon programmatore funzionale: P