320 likes | 529 Views
Zadavanje lista. Matematička notacija: {x2 | x {1...5}} U Haskelu: [x^2 | x [1..5]] Izraz x [1..5] zovemo generatorom liste. Lista se može zadati i sa više generatora: > [(x,y) | x [1,2,3], y [4,5]] [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)].
E N D
Zadavanje lista Matematička notacija: {x2 | x {1...5}} U Haskelu: [x^2 | x [1..5]] Izraz x [1..5] zovemo generatorom liste
Lista se može zadati i sa više generatora: > [(x,y) | x [1,2,3], y [4,5]] [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
Šta se dešava ako promenimo redosled generatora? > [(x,y) | y [4,5], x [1,2,3]] [(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
Zavisni generatori Kasniji generatorimoguzavisitiod promenljivih koje su uvedeni prethodnim generatorima. [(x,y) | x [1..3], y [x..3]] Lista [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)] svih parova (x,y) takvih dasu x,y elementi liste [1..3] and y x.
Primer • concat.hs
Dodatni uslovi pri definisanju lista(Guards) [x | x [1..10], even x] Primer: factors.hs
Funkcija zip zip :: [a] [b] [(a,b)] > zip [’a’,’b’,’c’] [1,2,3,4] [(’a’,1),(’b’,2),(’c’,3)] Primer: zip.hs
Stringovi • Stringovi predstavljaju liste karaktera "abc" :: String [’a’,’b’,’c’] :: [Char].
> length "abcde" 5 > take 3 "abcde" "abc" > zip "abc" [1,2,3,4] [(’a’,1),(’b’,2),(’c’,3)]
Zadaci • zadaci02.txt
Karijeve (Curried) funkcije Funkcije sa više argumenata moguće je koristeći funkciju kao povratnu vrednost definisati na sledeći način: add’ :: Int (Int Int) add’ x y = x+y add’ uzima kao argument ceo broj x vraća kao rezultat funkcijuadd’ x. Slično, ova funkcija uzima ceo broj y i vraća kao rezultat funkciju x+y.
Napomena: • add i add’ imaju isti konačan rezultat, ali add uzima svoja dva argumenta istovremeno, dok add’ uzima jedan po jedan argument: add :: (Int,Int) Int add’ :: Int (Int Int) • Funkcije koje uzimaju jedan po jedan argument zovu se Karijeve funkcije, u čast rada Haskell Curry-janad ovim funkcijama.
Funkcije sa više od dva argumenta mogu se definisati kao Karijeve kotrišćenjem ugnježdenih funkcija kao povratnih vrednosti: mult :: Int (Int (Int Int)) mult x y z = x*y*z mult uzima argument x i vraća funkciju mult x, koja slično uzimaargument y i vraća funkcijumult x y, koja na kraju uzima argument z ivraća rezultat x*y*z.
Zašto su Karijeve funkcije korisne? Karijeve funckije sufleksibilnije nego funkcije nad torkamajer se parcijalnom primenom Karijevh funkcija mogu dobiti razne korisne funkcije: Na primer: add’ 1 :: Int Int take 5 :: [Int] [Int] drop 5 :: [Int] [Int]
Konvencije u zapisu Karijevih funkcija • Strelicaje desno asocijativna. Da bi izbegli korišćenje zagrada kod Karijevih funkcija uvedene su dve jednostavne konvencije: Int Int Int Int Int (Int (Int Int)).
Kao posledica, prirodno je da primena funkcija bude levo asocijativna. mult x y z ((mult x) y) z. Osim kada torke nisu eksplicitno zahtevane, sve funkcije u Haskelu se obično definišu kao Karijeve.
Polimorfne funkcije Funkciju zovemopolimorfnom (“od više oblika”) ako njen tip sadrži jednu ili višetipskih promenljivih. length :: [a] Int za bilo koji tip a, length uzima listu vrednosti tipa a i vraća ceo broj.
Napomena: • Tipskim promenljivimmogu biti dodeljeni različiti tipovi: > length [False,True] 2 > length [1,2,3,4] 4 a = Bool a = Int • Tipske promenljive, za razliku od tipova, moraju počinjati malim slovom
Mnoge standardne funkcije definisane su kao polimorfne, npr: fst :: (a,b) a head :: [a] a take :: Int [a] [a] zip :: [a] [b] [(a,b)] id :: a a
Overloaded funkcije Polimorfnu funkcijuzovemooverloadedako njen tip sadrži jednu ili više tipskih promenljivih zadate u opsegu neke od klasa tipova: sum :: Num a [a] a Za svaki numerički tip a, suma uzima listu vrednosti tipa a i vraćavrednost tipa a.
Klase tipova • Klasa je kolekcija tipova kod kojih su definisane određene operacije • Eq – klasa jednakosti ==,\= • Ord – uredjeni tipovi <,>,<=,>=,min,max • Num – numericki tipovi +,-,*,negate,abs,signum
Integral – integralni tipovi div, mod • Fractional – tipovi razlomaka /, recip
Lambda izrazi Funkcije možemo zadati i preko lambda-izraza, npr: x x+x funkciji nije definisano ime; ona uzima argument x i vraća rezultat x+x.
Zašto su lambda izrazi korisni? Lambda izraziformalizuju značenje Karijevih funkcija: Na primer, funkcija add: add x y = x+y se može zapisati kao: add = x (y x+y)
Lambda izrazima se mogu definisati funkcije koje kao rezultat vraćaju funkciju Na primer, funkcija const: const :: a b a const x _ = x se prirodnije definiše kao: const :: a (b a) const x = _ x
Lambda izrazi dozvoljavaju da se izbegne imenovanje funkcija, što je pogodno ako npr definišemo funkciju koja se samo jednom koristi Na primer, funkcija odds: odds n = map f [0..n-1] where f x = x*2 + 1 se može jednostavnije zapisati ovako: odds n = map (x x*2 + 1) [0..n-1]
Sekcije Svaki operator koji se pišeizmeđusvoja dva argumentamože se zapisati kao Karijeva funkcijakoja se pišepresvojih argumenatakorišćenjem zagrada. Na primer: > 1+2 3 > (+) 1 2 3
Ova konvencija takođe dopušta da jedan od argumenata operatora bude naveden u zagradama. Na primer: > (1+) 2 3 > (+2) 1 3 Generalno, ako je operator,onda funkcije oblika (), (x) i (y) zovemosekcijama.
(1+) - funkcija sledbenik (1/) -funckija reciprociteta (*2) -funkcija udvostručavanja (/2) - funkcija polovljenja Zašto su sekcije korisne? Pomoću sekcija mogu se na jednostavan način definisati neke korisne funkcije, npr:
Zadatak • Pokazati kako se Karijeva funkcija mult x y z = x*y*z može definisati preko lambda izraza
Rekurzivne funkcije factorial 0 = 1 factorial (n + 1) = (n + 1) ∗ factorial n
Zadaci • Definisati rekurzivno operator za stepenovanje ^. • Definisati rekurzivno ugrađene funkcije: • and :: [Bool ] → Bool • concat :: [[a ]] → [a ] • replicate :: Int → a → [a ] • (!!) :: [a ] → Int → a (vraća n-ti element liste) • elem :: Eq a ⇒ a → [a ] → Bool (proverava da li je a element liste)