Haskell Hero

Interaktivní učebnice pro začínající Haskellisty

Funkce na seznamech I

head

Unární funkce vracející první prvek seznamu.

Definice

head       ::  [a] -> a
head (x:_)  =  x

Příklad použití

head [1,2,3]  ~>  1
head "ABC"  ~>  'A'
head [[2.5, 3.0], [4.8, 10.69, 9.12], []]  ~>  [2.5, 3.0]

tail

Unární funkce vracející seznam bez prvního prvku.

Definice

tail       ::  [a] -> [a]
tail (_:s)  =  s

Příklad použití

tail [1,2,3]  ~>  [2,3]
tail "ABC"  ~>  "BC"
tail [[2.5, 3.0], [4.8, 10.69, 9.12], []]
      ~>  [[4.8, 10.69, 9.12], []]

null

Unární funkce vracející True, pokud je seznam prázdný, False, pokud obsahuje alespoň jeden prvek.

Definice

null       ::  [a] -> Bool
null []     =  True
null (_:_)  =  False

Příklad použití

null []  ~>  True
null ""  ~>  True
null [2,3]  ~>  False
null "KK"  ~>  False

length

Unární funkce vracející délku seznamu.

Definice

length       ::  [a] -> Int
length []     =  0
length (x:s)  =  1 + length s

Příklad použití

length []  ~>* 0
length [1,2,3,4]  ~>*  4
length "ABCDE"  ~>*  5
length ["A", "AB", "&+#!$"]  ~>*  3

Vzorové vyhodnocení

length [1,2,3] neboli length 1:[2,3]

    za x se dosadí 1, za s se dosadí [2,3]
~>  1 + length [2,3]
    za x se dosadí 2, za s se dosadí [3]
~>  1 + 1 + length [3]
    za x se dosadí 3, za s se dosadí []
~>  1 + 1 + 1 + length []
    length [] se vyhodnotí podle první klauzule
~>  1 + 1 + 1 + 0
~>* 3

Poznámka

Jelikož se v definici na pravé straně druhé klauzule nevyskytuje x, můžeme jej nahradit podtržítkem.

length (_:s)  =  1 + length s

Spojování seznamů

Spojení dvou seznamů se provádí pomocí binárního operátoru (++). Vyhodnocení probíhá tak, že se prvky prvního seznamu po jednom přeskládají do druhého.

Definice

(++)       ::  [a] -> [a] -> [a]
[]    ++ t  =  t
(x:s) ++ t  =  x : (s ++ t)

Příklad použití

[1,2] ++ [3,4,5] ~>* [1,2,3,4,5]
"ABC" ++ "DE" ~>* "ABCDE"
[] ++ [True, False] ~> [True, False]

Vzorové vyhodnocení

[1,2,3] ++ [4]  což je zaměnitelné s 1:[2,3] ++ [4]

    podle druhé klauzule
    x = 1, s = [2,3], t = [4]
~>  1 : ([2,3] ++ [4])
    x = 2, s = [3], t = [4]
~>  1 : (2 : ([3] ++ [4]))
    x = 3, s = [], t = [4]
~>  1 : (2 : (3 : ([] ++ [4])))
    podle první klauzule
~>  1 : (2 : (3 : [4])) ≡ [1,2,3,4]

Poznámka

Při každém spojování seznamů se prvky z prvního seznamu musí přeskládat do seznamu druhého. To znamená, že vyhodnocení výrazu [1,2,3,4,5] ++ [] bude trvat podstatně delší dobu, než vyhodnocení výrazu [] ++ [1,2,3,4,5], které bude hotové po jednom kroku.

Výběr prvku

Prvek se ze seznamu vybírá pomocí binárního operátoru (!!). Výraz s !! k se vyhodnotí na k-tý prvek seznamu s.

  • indexuje se od nuly
  • předpokládá se, že k < length s, jinak dojde k chybě

Definice

(!!)       ::  [a] –> Int –> a
(x:_) !! 0  =  x
(_:s) !! k  =  s !! (k-1)

Příklad použití

[1,2,3] !! 0  ~>*  1
"ABCDE" !! 4  ~>*  'E'
[[1,2], [3], [], [4,5]] !! 3  ~>*  [4,5]

take

Binární funkce, kde výraz take n s se vyhodnotí na seznam obsahující prvních n prvků seznamu s. Pokud n > length s, vrátí se celý seznam s.

Definice

take         ::  Int –> [a] –> [a]
take 0 _      =  []
take _ []     =  []
take n (x:s)  =  x : take (n-1) s

Příklad použití

take 2 [1,2,3,4] ~>* [1,2]
take 3 [2] ~>* [2]
take 1 "ABCD" ~>* "A"

drop

Binární funkce, kde se výraz drop n s vyhodnotí na seznam s bez prvních n prvků. Pokud n > length s, výraz se vyhodnotí na prázdný seznam.

Definice

drop         ::  Int –> [a] –> [a]
drop 0 s      =  s
drop _ []     =  []
drop n (_:s)  =  drop (n-1) s

Příklad použití

drop 2 [1,2,3,4,5]  ~>*  [3,4,5]
drop 0 [1,2,3]  ~>*  [1,2,3]
drop 8 [1,2,3]  ~>*  []

concat

Unární funkce, která spojí seznamy v seznamu seznamů v jeden seznam.

Definice

concat       ::  [[a]] –> [a]
concat []     =  []
concat (s:t)  =  s ++ concat t

Příklad použití

concat [[1,2], [3,4,5], [], [6,7]]  ~>*  [1,2,3,4,5,6,7]
concat ["ABC", "", "DEF"]  ~>*  "ABCDEF"