Ми реалізуємо бібліотеку стиснення матриць на основі модифікованого синтаксису двомірної граматики. Зараз у нас є два підходи для наших типів даних - який буде кращим у випадку використання пам'яті? (ми хочемо щось стиснути;)).
Граматики містять NonTerminals з точно 4-ма творами або терміналом праворуч. Нам потрібні назви виробництва для перевірки рівності та мінімізації граматики.
Перший:
-- | 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
}
Тут наші дані RightHandSide зберігають лише імена рядків для визначення наступних постановок, і те, що ми тут не знаємо, - як Haskell зберігає ці рядки. Наприклад, матриця [[0, 0], [0, 0]] має 2 виробництва:
a = Terminal 0
aString = "A"
b = DownStep aString aString aString aString
bString = "B"
productions = Map.FromList [(aString, a), (bString, b)]
Тож питання тут полягає в тому, як часто рядок "A" дійсно зберігається? Один раз в aString, 4 рази в b і один раз в постановках або просто один раз в aString та інші просто містять «дешевші» посилання?
Другий:
data Production = NonTerminal String Production Production Production Production
| Terminal String Int
type ProductionMap = Map String Production
тут термін "Термінал" трохи вводить в оману, оскільки його фактично є виробництво, яке має термінал як праву сторону. Та сама матриця:
a = Terminal "A" 0
b = NonTerminal "B" a a a a
productions = Map.fromList [("A", a), ("B", b)]
і подібне питання: як часто продукція Haskell внутрішньо економиться? Можливо, ми викинемо імена всередині постановок, якщо вони нам не знадобляться, але ми зараз не впевнені в цьому.
Тож скажімо, у нас є граматика з близько 1000 творів. Який підхід буде споживати менше пам’яті?
Нарешті, питання про цілі числа в Haskell: В даний час ми плануємо назвати ім'я як Strings. Але ми могли б легко перейти до цілих імен, тому що з 1000 виробництв у нас з'являться імена з більш ніж 4 символами (що я вважаю, це 32 біт?). Як справляється з цим Haskell. Чи Int завжди 32-бітний і цілий виділяє пам'ять, яка йому справді потрібна?
Я також прочитав це: Розробка тесту на значення / еталонну семантику Haskell - але я не можу зрозуміти, що саме це для нас означає - я більше імперативний дитина Java, а потім хороший функціональний програміст: P