zadavanje lista
DESCRIPTION
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)]. - PowerPoint PPT PresentationTRANSCRIPT
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 generatori mogu zavisiti od 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 da su 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
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 funkciju add’ x.
Slično, ova funkcija uzima ceo broj y i vraća kao rezultat funkciju x+y.
Karijeve (Curried) funkcije
add i add’ imaju isti konačan rezultat, ali add uzima svoja dva argumenta istovremeno, dok add’ uzima jedan po jedan argument:
Napomena:
Funkcije koje uzimaju jedan po jedan argument zovu se Karijeve funkcije, u čast rada Haskell Curry-ja nad ovim funkcijama.
add :: (Int,Int) Int
add’ :: Int (Int Int)
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 uzima argument y i vraća
funkciju mult x y, koja na kraju uzima argument z i vraća rezultat x*y*z.
Zašto su Karijeve funkcije korisne?
Karijeve funckije su fleksibilnije nego funkcije nad torkama jer 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
Strelica je desno asocijativna.
Int Int Int Int
Da bi izbegli korišćenje zagrada kod Karijevih funkcija uvedene su dve jednostavne konvencije:
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 zovemo polimorfnom (“od više oblika”) ako njen tip sadrži jednu ili više tipskih promenljivih.
length :: [a] Int
za bilo koji tip a, length uzima listu vrednosti tipa a i vraća ceo broj.
Tipskim promenljivim mogu biti dodeljeni različiti tipovi:
Napomena:
Tipske promenljive, za razliku od tipova, moraju počinjati malim slovom
> length [False,True]2
> length [1,2,3,4]4
a = Bool
a = Int
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 funkciju zovemo overloaded ako 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ća vrednost 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 tipovidiv, 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 izrazi formalizuju značenje Karijevih funkcija:
Na primer, funkcija add:
add x y = x+y
add = x (y x+y)
se može zapisati kao:
const :: a b aconst x _ = x
se prirodnije definiše kao:
const :: a (b a)const x = _ x
Lambda izrazima se mogu definisati funkcije koje kao rezultat vraćaju funkcijuNa primer, funkcija const:
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]
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:
Sekcije
Svaki operator koji se piše između svoja dva argumenta može se zapisati kao Karijeva funkcija koja se piše pre svojih argumenata korišćenjem zagrada.
Na primer:
> 1+23
> (+) 1 23
Ova konvencija takođe dopušta da jedan od argumenata operatora bude naveden u zagradama.
Na primer: > (1+) 23
> (+2) 13
Generalno, ako je operator, onda funkcije oblika (), (x) i (y) zovemo sekcijama.
Zašto su sekcije korisne?
Pomoću sekcija mogu se na jednostavan način definisati neke korisne funkcije, npr:
- funkcija sledbenik
- funckija reciprociteta
- funkcija udvostručavanja
- funkcija polovljenja
(1+)
(*2)
(/2)
(1/)
Zadatak
Pokazati kako se Karijeva funkcijamult x y z = x*y*z može definisati
preko lambda izraza
Rekurzivne funkcije
factorial 0 = 1factorial (n + 1) = (n + 1) ∗ factorial
n
Zadaci
1. Definisati rekurzivno operator za stepenovanje ^.
2. Definisati rekurzivno ugrađene funkcije:1) 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)