Tuple, Lista, Listagenerátor
Tuple
A rendezett n-esek közül a leggyakrabban használt a rendezett kettes, amelyet tuple-nak is neveznek. A tuple-t a következőképpen definiáljuk:
(<elem1>, <elem2>)
A tuple-re vannak előre definiált függvények, amelyek segítségével könnyen hozzáférhetünk az elemekhez.
fst :: (a,b) -> a
fst (x,_) = x
snd :: (a,b) -> b
snd (_,y) = y
Lista
A String is egy karakter lista (String = [Char]).
"Hello" == ['H','e','l','l','o']
Listagenerátor
A lista generátor egy kifejezés, amely egy listát ad eredményül.
Egyszerű listagenerátor
Négy függvényt lehet használni listagenerálásra, mindegyiknek létezik "szintaktikus cukorka" alakja:
- enumFromTo 1 10 == [1..10] -> [1,2,3,4,5,6,7,8,9,10]
- enumFromThenTo 1 3 10 == [1,3..10] -> [1,3,5,7,9]
- enumFrom 1 == [1..] -> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15... Végtelen lista]
- enumFromThen 1 3 == [1,3..] -> [1,3,5,7,9,11,13,15... Végtelen lista]
Amennyiben nem adjuk meg az egész szám típusát a fordító automatikusan Integert választja, így lehetséges végtelen listát létrehozni. Ha a számnak Int típusa van akkor a lista nem végtelen.
[(1::Int), ((maxBound::Int)-1)..] == [1,9223372036854775806]
Ez leegyszerűsíthető a következő alakra:
[<kezdőérték> (, <lépésköz>) .. (<végérték>)]
Halmazszerű listagenerátor
Létezik egy a matematiaki halmazokat utánzó leírása is:
[<kifejezés> | <változó> <- <lista>]
Ezzel kifejezhető például a következő halmaz: {x^2 | x ∈ {1..5}}
[x^2 | x <- [1..5]]
A <változó> <-
Több generátort is lehet használni egy listagenerátorban, ezeket vesszővel választjuk el egymástól.
[(x,y) | x <- [1..3], y <- [1..2]]
Ez a kifejezés a generátorok Descartes szorzatát adja eredményül.
[(1,1),(1,2),(2,1),(2,2),(3,1),(3,2)]
Szűrőfeltétel
A listagenerátorokban lehetőség van szűrőfeltétel megadására is. A szűrőfeltételt a generátorok után vesszővel elválasztva kell megadni.
[x | x <- [1..], x `mod` 2 == 0]
Ez a kifejezés a páros számok listáját adja eredményül.
evenList :: [Integer]
evenList = [x | x <- [1..], x `mod` 2 == 0]
evenList = [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30...] Végtelen lista
Mintaillesztés listára
A listák mintaillesztésére is van lehetőség. Mintát lehet illeszteni pontos elemszámra, illetve a lista első elemére és a maradékára.
null' :: [a] -> Bool
null' [] = True -- üres lista
null' _ = False
singleton :: [a] -> Bool
singleton [_] = True -- egy elem van a listában
singleton _ = False
twoOrMore :: [a] -> Bool
twoOrMore (_:_:_) = True -- legalább két elem van a listában
twoOrMore _ = False
firstTwo :: [a] -> (a,a)
firstTwo (x:y:_) = (x,y)
-- parciális függvény, ha a lista kevesebb mint két elemű akkor execption-t dob
keepFirstThree :: [a] -> [a]
keepFirstThree (x:y:z:_) = [x,y,z]
keepFirstThree (x:y:_) = [x,y]
keepFirstThree [x] = [x]
keepFirstThree _ = []
Létezik a head
és tail
függvény, amelyek segítségével a lista első eleméhez és a maradékához lehet hozzáférni, valamint a last
és init
függvények, amelyek segítségével a lista utolsó eleméhez és a lista első elem nélküli részéhez lehet hozzáférni.
```haskell
head' :: [a] -> a
head' (x:_) = x
tail' :: [a] -> [a]
tail' (_:xs) = xs
last' :: [a] -> a
last' [x] = x -- egy elem van a listában
last' (_:xs) = last' xs -- rekurzió: Negyedik lecke
init' :: [a] -> [a]
init' [x] = [] -- egy elem van a listában
init' (x:xs) = x : init' xs -- rekurzió: Negyedik lecke
Mint látható mindegyik függvény parciális így nem tudnak kezelni üres listát. A head
, tail
, last
és init
függvényeket csak akkor használjuk, ha tudjuk hogy a lista nem üres.