Haskell Hero

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

Funkce na seznamech III

takeWhile

takeWhile je binární funkce, jejímiž argumenty jsou:

  • podmínková funkce p, která z čehokoli udělá Bool, typ a -> Bool
  • seznam čehokoli, co se dá dát funkci p jako argument, typ [a]

Výraz takeWhile p s se vyhodnotí na takový začátek seznamu s, kde všechny jeho prvky vyhoví podmínce p.

Definice

takeWhile         ::  (a -> Bool) -> [a] -> [a]
takeWhile _ []     =  []
takeWhile p (x:s)  =  if p x then x : takeWhile p s
                             else []

Příklady

takeWhile (<5) [1,2,6,7,3,4]      ~>*  [1,2]
takeWhile even [2,4,6,5,7,8]      ~>*  [2,4,6]
takeWhile  id  [False,True,True]  ~>*  []

dropWhile

dropWhile je binární funkce, která si, stejně jako funkce takeWhile, bere následující argumenty:

  • podmínkovou funkci p, která z čehokoli udělá Bool, typ a -> Bool
  • seznam čehokoli, co se dá dát funkci p jako argument, typ [a]

Výraz dropWhile p s se vyhodnotí na takový konec seznamu s, že se zahodí všechny prvky z jeho začátku, které vyhoví podmínce p.

Definice

dropWhile         ::  (a -> Bool) -> [a] -> [a]
dropWhile _ []     =  []
dropWhile p (x:s)  =  if p x then dropWhile p s
                             else (x:s)

Příklady

dropWhile (<5) [1,2,6,7,3,4]         ~>*  [6,7,3,4]
dropWhile even [2,4,6,9,8,7]         ~>*  [9,8,7]
dropWhile  id  [True, False, False]  ~>*  [False,False]

zip

zip je binární funkce, která si jako argumenty bere dva seznamy čehokoli, s a t, ze kterých udělá seznam dvojic (x,y), kde x je ze seznamu s a y ze seznamu t. Výsledný seznam je pak dlouhý jako kratší ze seznamů s a t.

Definice

zip             ::  [a] -> [b] -> [(a,b)]
zip  []    _     =  []
zip  _     []    =  []
zip (x:s) (y:t)  =  (x,y) : zip s t

Příklady

zip [1,2,3] [4,5,6]       ~>*  [(1,4),(2,5),(3,6)]
zip "abcde" [True,False]  ~>*  [('a',True),('b',False)]
zip [] ["ab","cd"]        ~>*  []

unzip

unzip je unární funkce, která ze seznamu dvojic udělá dvojici seznamů, kde v prvním seznamu budou všechny první složky dvojic a ve druhém seznamu budou všechny složky druhé.

Definice

unzip            ::  [(a,b)] -> ([a],[b])
unzip  []         =  ([],[])
unzip  ((x,y):s)  =  (x:t,y:u)
                        where (t,u) = unzip s

Příklady

unzip [(1,2),(3,4),(5,6)]       ~>*  ([1,3,5],[2,4,6])
unzip [(True,'c'),(False,'s')]  ~>*  ([True,False],"cs")

zipWith

zipWith je ternární funkce, která si bere:

  • binární funkci f, která z nějakého a a b udělá c, typ a -> b -> c
  • seznam čehokoli, co se dá dát funkci f jako první argument, typ [a]
  • seznam čehokoli, co se dá dát funkci f jako druhý argument, typ [b]

Výraz zipWith f s t se pak vyhodnotí na seznam tvořený výsledky aplikace funkce f na prvky seznamů s a t, typ [c]. Výsledný seznam bude dlouhý jako kratší ze seznamů s a t.

Definice

zipWith _ [] _         =  []
zipWith _ _ []         =  []
zipWith f (x:s) (y:t)  =  (f x y) : zipWith f s t

Příklady

zipWith (+) [3,5,4] [2,1,5,8]  ~>*  [3 + 2, 5 + 1, 4 + 5]
zipWith (:) "abc" ["def","ghi"]  ~>*  ["adef","bghi"]

Poznámka

Funkci zip můžeme se znalostí funkce zipWith definovat následovně:

zip  =  zipWith (,)