Obsah
Vzhledem k tomu, že Haskell je funkcionální jazyk, očekávali bychom, že budou funkce hrát významnou roli, a tak tomu skutečně je. V této sekci se podíváme na některé aspekty funkcí jazyka Haskell.
Nejprve uvažujme následující definici funkce, která sečte své dva argumenty:
add :: Int -> Int -> Int add x y = x + y
Je to příklad funkce v tzv. Curryho tvaru. Abychom dosáhli efektu funkce, která v tomto tvaru není, mohli bychom použít n-tici, jako např.:
add (x,y) = x + yAvšak nyní vidíme, že tato verze add je vlastně funkcí jednoho argumentu! Volání add má tvar add e1 e2 a je ekvivalentní (add e1) e2, neboť volání funkce je asociativní zleva. Jinými slovy, volání add s jediným argumentem je nová funkce, která je dále volána na druhý argument. To je konzistentní s typem add, Int->Int->Int, jenž je ekvivalentní Int->(Int->Int); tj. operátor -> je asociativní zprava. A skutečně pomocí add můžeme definovat funkci inc jinak, než jak jsme to provedli dříve:
inc = add 1
Toto je příklad částečného volání funkce a je to jedna z možností, jak můžeme funkci vrátit jako výsledek. Uvažujme případ, v němž je užitečné předávat funkci jako argument. Dokonalým příkladem je velmi známá funkce map:
map :: (a->b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs
![]() | Poznámka: |
Volání funkce má vyšší prioritu než libovolný infixový operátor, a tedy
pravá strana druhé rovnice se přeloží jako
(f x) : (map f xs).
| |
Funkce map je polymorfní a její typ jasně ukazuje, že jejím prvním argumentem je funkce; všimněte si také, že obě typové proměnné a musí být instancovány tímtéž typem (totéž platí pro obě b). Příkladem použití map je inkrementace všech prvků seznamu:
map (add 1) [1,2,3] => [2,3,4]
Tyto příklady demonstrují „prvotřídní“ podstatu funkcí, které se v těchto situacích nazývají funkce vyššího řádu.