Haskell je čistě funkcionální jazyk, proto se všechny výpočty provádějí tak, že se vyhodnocením výrazů (syntaktických termů) získávají hodnoty (abstraktní entity, které považujeme za odpovědi). S každou hodnotou je svázán její typ. (Intuitivně chápeme typy jako množiny hodnot.) Příkladem výrazů jsou atomické hodnoty jako celé číslo 5, znak 'a' a funkce \x -> x+1, ale také strukturované hodnoty jako je seznam [1,2,3] a dvojice ('b',4).
Stejně jako výrazy označují hodnoty, jsou typové výrazy syntaktické termy označující typové hodnoty (nebo pouze typy). Příklady typových výrazů jsou atomické typy Int (celá čísla s pevně definovanou přesností), Char (znaky), Int->Int (funkce zobrazující Int na Int), stejně jako strukturované typy [Int] (homogenní seznamy celých čísel) a (Char,Int) (dvojice znak, celé číslo).
Všechny hodnoty v jazyce Haskell jsou „plnoprávné“ - mohou být předávány jako argumenty funkcím, vráceny jako výsledky, umístěny v datových strukturách atd. Na druhé straně typy jazyka Haskell nejsou plnoprávné. Typy v jistém smyslu popisují hodnoty a propojení hodnoty s jejím typem se označuje jako typování. Pomocí výše uvedených příkladů hodnot a typů zapisujeme typování takto:
5 :: Int 'a' :: Char inc :: Int -> Int [1,2,3] :: [Int] ('b',4) :: (Char,Int)Symbol „::“ můžeme číst jako „má typ.“
Funkce se v jazyce Haskell normálně definují posloupností rovnic. Například funkci inc můžeme definovat jedinou rovnicí:
inc n = n+1Rovnice je příkladem deklarace. Dalším druhem deklarace je deklarace signatury typu, pomocí níž můžeme deklarovat explicitní typování pro inc:
inc :: Int -> Int
Pokud budeme chtít uvést, že se výraz e1 vyhodnotí, nebo též „zredukuje“ na jiný výraz nebo hodnotu e2, budeme psát:
Například můžeme psát, že:
Statický typový systém definuje formální vztah mezi typy a hodnotami. Statický typový systém zajišťuje, že programy v Haskellu jsou typově bezpečné, tj. že programátor nějakým způsobem nezpůsobil nějaký zmatek. Například obecně nelze sečítat dva znaky, takže výraz 'a'+'b' je špatně typovaný. Hlavní výhoda staticky typovaných jazyků je všeobecně známá: Všechny typové chyby se detekují v době překladu. Ne všechny chyby jsou ale zachyceny typovým systémem; výraz jako 1/0 je typovatelný, ale jeho vyhodnocení způsobí v době provádění výpočtu chybu. I přesto typový systém odhalí v době překladu mnoho chyb, pomáhá uživateli při dokazování programů a umožňuje překladači generovat efektivnější kód (například nejsou v době běhu potřeba žádné testy typových příznaků).
Typový systém rovněž zajišťuje, že uživatelem dodané signatury typů jsou správné. Ve skutečnosti je typový systém jazyka Haskell natolik mocný, že umožňuje (až na pár výjimek popsaných později) uživateli se psaní signatur typů zcela vyhnout. Říkáme, že nám typový systém správný typ odvodí. Nicméně pečlivé uvádění typových signatur, jako jsme učinili v případě inc, je dobrá myšlenka, neboť typové signatury jsou velmi efektivní formou dokumentace a umožňují vynést na světlo programátorské chyby.
![]() | Poznámka: |
Určitě jste si povšimli, že identifikátory označující specifické typy
jako Int a Char zapisujeme s velkým počátečním
písmenem, zatímco identifikátory označující hodnoty jako
inc s malým počátečním písmenem.
Není to pouze konvence, ale je to vyžadováno lexikální syntaxí jazyka
Haskell. Ve skutečnosti se vždy malá a velká písmena rozlišují:
foo, fOo a fOO
jsou navzájem různé identifikátory.
| |