Funkcionális programozás 5. el adás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2019, tavaszi félév
Mir l volt szó? a Haskell kiértékelési stratégiája függvények listákon: map, null, lter, reverse take, takewhile, drop, dropwhile, elem, zip, splitat, iterate, repeat, replicate, any, all Haskell modulok, kompilálás
Mir l lesz szó? feladatmegoldás a Show és Read típusosztályok explicit típuskonverziók a struct típus rendezések: beszúrásos rendezés (insert sort), gyorsrendezés (quick sort)
A Show és Read típusosztályok A Show osztály példányai azok a típusok, amelyek átalakíthatóak stringgé. Legtöbbször az I/O m veletek során használjuk. Legegyszer bb függvénye: show :: (Show a) => a -> String > let x = 2 > let y = 4 > let strl = "A " ++ show x ++ " es "++ show y ++ " osszege = "++ show (x + y) > strl "Az 2 es 4 osszege = 6" > show [45, 3, 12, 101, 61] "[45, 3, 12, 101, 61]"
A Show és Read típusosztályok A Read osztály példányai azok a típusok, amelyekre az ellenkez m veletek végezhet ek, mint a Show osztály példányaira. Legegyszer bb függvénye: read :: (Read a) => String -> a, amely megadott típussá átalakítja a String típust. specikálni kell a kimenet típusát > read "5.12" :: Double 5.12 > read "[1, 2, 3]" :: [Int] [1,2,3] > read ["1", "2", "3"] :: [Int] <interactive>:15:7: error:...
A Show és Read típusosztályok readl :: [String] -> [Int] readl str = map read str > readl ["101", "41", "1789"] [101,41,1789] > map (read :: String -> Int) ["101", "41", "1789"] [101,41,1789] > map (read :: String -> Int) $ words "12 34 56" [12,34,56] Megjegyzés: > words "12 45 67 780" ["12","45","67","780"] > words "sapientia egyetem" ["sapientia","egyetem"]
Explicit típuskonverziók Egész típusra (Integral type) való konverzió: Integral (Integer, Int) típusról alakít egy értéket Num (Int, Integer Rational, Double) típusra: fromintegral :: (Num b, Integral a) => a -> b > let negyzetgy n = sqrt (fromintegral n) > negyzetgy 10 3.1622776601683795 Két sajátos formája is van: frominteger :: Num a => Integer -> a tointeger:: Integral a => a -> Integer
Explicit típuskonverziók real típusú értékek és real-fractional típusú értékek közötti átalakítások, ahol a real típus lehet Integral, real-fractional és real-fractional típus lehet Rational, Double típus. A Rational típus végtelen pontosságú törteket jelent realtofrac:: (Real a, Fractional b) => a -> b fromrational :: Fractional a => Rational -> a torational :: Real a => a -> Rational > 1 % 2 + 1 % 3 5 % 6 > torational 1.3 5854679515581645 % 4503599627370496 > torational (fromrational (13 % 10)) 5854679515581645 % 4503599627370496
A struct típus Lehet ség van "saját" típus, új adatszerkezet létrehozására: a data kulcsszó segítségével. data Szemely = Szemely{ nev :: String, jegy :: Double, ev :: Int } deriving (Show) ahol Szemely konstruktor és típus-kontstruktor is egyben. Ha csak egy érték-konstruktor van akkor nem szükséges különböz nevet választani. A deriving kulcsszóval különböz m veletek denícióját adhatjuk meg. A Show osztály a szöveggé alakítást, a kiírást teszi lehet vé.
A struct típus Konstans értékekkel való inicializálás: valaki1 = Szemely "Mari" 4.5 1 szemelyl :: [Szemely] szemelyl = [Szemely "Sari" 8.75 1, Szemely "Mari" 4.25 1, Szemely "Feri" 3.5 2, Szemely "Zsuzsi" 10.0 2, Szemely "Laci" 8.5 2, Szemely "Lori" 7.5 2] Mez értékének a módosítása: modosit :: Szemely -> Double -> Int -> Szemely modosit sze j e = sze {jegy = j, ev = e} Meghívása után a jegy 8.7-re és az ev 2-re módosul: modosit valaki1 8.7 2
Feladatok 1. feladat Számoljuk meg, hogy hány diáknak van átmen jegye. szamol :: [Szemely] -> Int szamol [] = 0 szamol (k: ve) jegy k > 4.5 = 1 + szamol ve otherwise = szamol ve > szamol szemelyl 2
Feladatok 2. feladat Tegyük át egy listába az els éves személyeket valogat :: Int -> [Szemely] -> [Szemely] valogat e [] = [] valogat e (k: ve) ev k == e = (k: valogat e ve) otherwise = valogat e ve > valogat 1 szemelyl [Szemely nev = "Sari", jegy = 8.75, ev = 1,... Második módszer: valogat_ :: Int -> [Szemely] -> [Szemely] valogat_ e ls = [k k <- ls, ev k == e]
Feladatok 3. feladat Határozzuk meg egy listában lev elemek átlagát. atlag :: (Fractional a) => [a] -> a atlag ls = ossz / db where (ossz, db) = satlag ls satlag :: (Fractional a) => [a] -> (a, a) satlag [] = (0.0, 0.0) satlag (k: ve) = (k + temp1, 1 + temp2) where (temp1, temp2) = satlag ve > atlag [1,2,3,6] 3.2
A struct típus: átlagszámolás 4. feladat Határozzuk meg a szemelyl listában lev személyek átlagát. data Szemely = Szemely{ nev :: String, jegy :: Double, ev :: Int } deriving (Show) szemelyl :: [Szemely] szemelyl = [Szemely "Sari" 8.75 1, Szemely "Mari" 4.25 1, Szemely "Feri" 3.5 2, Szemely "Zsuzsi" 10.0 2, Szemely "Laci" 8.5 2, Szemely "Lori" 7.5 2]
A struct típus: átlagszámolás 1. módszer atlagsz :: [Szemely] -> Double atlagsz ls = ossz / db where (ossz, db) = satlag ls satlag ls null ls = (0.0, 0.0) otherwise = (jegy k + temp1, 1 + temp2) where (temp1, temp2) = satlag ve k = head ls ve = tail ls > atlagsz szemelyl 7.083333333333333
A struct típus: átlagszámolás 2. módszer atlagsz :: [Szemely] -> Double atlagsz ls = ossz / db where ossz = sum lsj db = fromintegral (length ls) lsj = valogatj ls valogatj ls = [jegy k k <- ls] > atlagsz szemelyl 7.083333333333333
A struct típus: átlagszámolás 3. módszer atlagsz :: [Szemely] -> Double atlagsz ls = let satlag ls = let k = head ls ve = tail ls (temp1, temp2) = satlag ve in if null ls then (0.0, 0.0) else (jegy k + temp1, 1 + temp2) (ossz, db) = satlag ls in ossz / db > atlagsz szemelyl 7.083333333333333
Beszúrásos rendezés Adott elem beszúrása rendezett listába ins :: (Ord a) => a -> [a] -> [a] ins x [] = [x] ins x (k: ve) x > k = (k: ins x ve) otherwise = (x: (k: ve)) > ins 'h' "abcdeklmno" "abcdehklmno" > ins "racionalis" ["egesz", "komplex", "valos"] ["egesz","komplex","racionalis","valos"]
Beszúrásos rendezés inserts :: (Ord a) => [a] -> [a] inserts [] = [] inserts (k: ve) = ins k (inserts ve) > inserts [3,12,7,8,4,5,11] [3,4,5,7,8,11,12] > inserts "acbdeklhmno" "abcdehklmno"
Gyorsrendezés quicks :: (Ord a) => [a] -> [a] quicks [] = [] quicks (k: ve) = quicks klista ++ [k] ++ quicks nlista where klista = [x x <- ve, x < k] nlista = [x x <- ve, x >= k] > quicks [7,5,9,10,13,2,3,11] [2,3,5,7,9,10,11,13]
Összefésüléses rendezés A merges a merge függvény segítségével rendezi a paraméterként megadott lista elemeit. mergesort :: (Ord a) => [a] -> [a] mergesort [] = [] mergesort [k] = [k] mergesort ls = merge blista jlista where db = div (length ls) 2 blista = mergesort (take db ls) jlista = mergesort (drop db ls) > merges [3,12,6,7,5,9,10,2,10,1] [1,2,3,5,6,7,9,10,10,12]