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ó> <- kifejezést generátornak nevezzük.

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.