Funkcionalno programiranje Funkcionalni parseri Interaktivni programi
Šta je parser? Parser je program koji analizira tekst kako bi odredio njegovu sintaktičku strukturu: 4 + 2 3 23+4
Razni programi koje svakodnevno koristimo imaju neke vrste parsera kojima preprocesiraju svoje ulazne podatke: Haskell programs Shell scripts HTML documents Hugs Unix Explorer
Parser je funkcija koja uzima string i vraća neki oblik drveta Tip parsera U Haskelu, parsere možemo prirodno posmatrati kao funkcije: type Parser = String Tree Parser je funkcija koja uzima string i vraća neki oblik drveta
Međutim, parser možda neće iskoristiti čitav string, pa u povratnu vrednost dodajemo i taj neiskorišćeni deo: type Parser = String (Tree,String) String se može parsirati na više načina, a nekad se i ne može parsirati, pa je pogodno vratiti listu rezultata: type Parser = String [(Tree,String)]
Da se ne bi ograničavali samo na strukuturu drveta, generalizujemo tip parsera tako da povratna vrednost bude bilo kog tipa: type Parser a = String [(a,String)]
Deklaracija klasi i instanci u Haskelu Uvođenje novih klasa: class Eq a where (==), (\=) :: a → a → Bool x \= y = ¬(x == y)
Uvođenje instanci klasa: instance Eq Bool where False == False = True True == True = True _==_ = False
Monadički tipovi class Monad m where return :: a → m a (>>=) :: m a → (a → m b) → m b
Primer instance monade instance Monad Parser where return v = · · · p >>= f = · · ·
Notacija do do v1 ← e1 e1 >>= λv1 → v2 ← e2 e2 >>= λv2 → ... vn ← en return (f v1 v2 ... vn) e1 >>= λv1 → e2 >>= λv2 → ... en >>= λvn → return (f v1 v2 ... vn)
Primer parser.hs
Izgradnja gramatike za parser za aritmetičke izraze Hoćemo da konstruišemo parser koji bi izračunavao vrednost aritmetičkog izraza: 2*3+4 10 2*(3+4) 14 2 * 3 + 4
Instanca 1 expr ::= expr + expr | expr ∗ expr | (expr) | nat
Za izraz 2*3+4 imamo dva moguća drveta izvođenja, jer naša gramatika ne uzima u obzir da množenje ima veći prioritet od sabiranja
Instanca 2 expr ::= expr + expr | term term ::= term ∗ term | factor factor ::= (expr) | nat nat ::= 0 | 1 | 2 | · · · U ovakvoj gramatici postoji jedinstveno drvo izvođenja za 2*3+4
Međutim, gramatika još uvek ne uzima u obzir da su množenje i deljenje asocijativne operacije, što prouzrokuje više mogućih drveta izvođenja npr za izraz 2+3+4, koji može biti protumačen kao (2+3)+4 i kao 2+(3+4)
Instanca 3 expr ::= term + expr | term term ::= factor ∗ term | factor što se može dalje pojednostaviti radi lakše implementacije: expr ::= term (+ expr |epsilon ) term ::= factor (∗ term |epsilon)
Primer arexp.hs
Zadatak Proširiti gramatiku i parser tako da se omogući stepenovanje. Podrazumeva se da je stepenovanje desno asocijativno i da ima veći prioritet od množenja i deljenja, ali manji od zagrada i brojeva.
Interaktivni programi Do sada smo videli kako se u Haskelu pišu tzv. batch programi, koji uzimaju ulazne podatke na početku i daju izlazne na kraju, bez ikakvih sporednih efekata batch program inputs outputs
Međutim, želeli bismo da koristimo Haskel za pisanje interaktivnih programa koji u toku izvršavanja mogu čitati podatke sa ulaza i pisati na izlaz interactive program inputs outputs keyboard screen
Problem Haskel programi nemaju sporedne efekte. Haskel programi su čiste matematičke funkcije: Haskel programi nemaju sporedne efekte. Čitanje sa tastature i ispis na ekran su sporedni efekti: Interaktivni programi imaju sporedne efekte.
Tip akcija koje vraćaju vrednost tipa a Rešenje Interaktivni programi se mogu pisati u Haskelu korišćenjem tipova koji bi razlikovali “čiste” izraze od “nečistih” akcija koje mogu obuhvatati sporedne efekte IO a Tip akcija koje vraćaju vrednost tipa a
Tip akcija koje vraćaju karakter. Na primer: IO Char Tip akcija koje vraćaju karakter. Tip akcija koje obuhvataju samo sporedne efekte i nemaju povratnu vrednost IO () Napomena: () je tip torke koja sadrži 0 komponenata.
Primer io.hs