Değiştirilmiş iki boyutlu dilbilgisi sözdizimine dayalı bir matris sıkıştırma kütüphanesi uyguluyoruz. Şimdi veri tiplerimiz için iki yaklaşımımız var - bellek kullanımı durumunda hangisi daha iyi olacak? (bir şeyi sıkıştırmak istiyoruz;)).
Dilbilgisi, tam olarak 4 Prodüksiyona sahip olmayan Terminaller veya sağ tarafta bir Terminal içerir. Eşitlik kontrolleri ve dilbilgisi minimizasyonu için Productions isimlerine ihtiyacımız olacak.
İlk:
-- | 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
}
Burada RightHandSide verilerimiz, bir sonraki yapımları belirlemek için yalnızca String adlarını kaydeder ve burada bilmediğimiz şey Haskell'in bu karakter dizilerini nasıl kaydettiğidir. Örneğin [[0, 0], [0, 0]] matrisinin 2 prodüksiyonu vardır:
a = Terminal 0
aString = "A"
b = DownStep aString aString aString aString
bString = "B"
productions = Map.FromList [(aString, a), (bString, b)]
Buradaki soru, "A" Stringinin ne sıklıkta kaydedildiğidir? Bir kez aString, 4 kez b ve bir kez yapımlarda veya sadece bir kez aString ve diğerleri sadece "daha ucuz" referanslar tutuyor?
İkinci:
data Production = NonTerminal String Production Production Production Production
| Terminal String Int
type ProductionMap = Map String Production
burada "Terminal" terimi biraz yanıltıcıdır, çünkü aslında sağ taraftaki bir terminale sahip olan üretimdir. Aynı Matris:
a = Terminal "A" 0
b = NonTerminal "B" a a a a
productions = Map.fromList [("A", a), ("B", b)]
ve benzer soru: üretim Haskell tarafından dahili olarak ne kadar tasarruf ediliyor? Muhtemelen onlara ihtiyacımız yoksa isimleri yapımların içine bırakacağız, ancak şu anda bu konuda emin değiliz.
Diyelim ki yaklaşık 1000 prodüksiyona sahip bir gramerimiz var. Hangi yaklaşım daha az bellek tüketir?
Son olarak Haskell'deki tamsayılarla ilgili bir soru: Şu anda Dizeler olarak isim almayı planlıyoruz. Ama kolayca tamsayı isimlerine geçebiliriz, çünkü 1000 yapımında 4 karakterden daha uzun isimlere sahip olacağız (ki 32 bit olduğunu varsayıyorum). Haskell bunu nasıl halleder. Int her zaman 32 Bit ve Integer gerçekten ihtiyaç duyduğu belleği ayırır mı?
Bunu da okudum: Haskell'in değer / referans anlambilim testinin geliştirilmesi - ama bunun bizim için tam olarak ne anlama geldiğini anlayamıyorum - Ben daha çok zorunlu bir java çocuğuyum, sonra iyi bir işlevsel programcı: P