beta

Úvod

O tomto tutoriálu

Vítejte v příručce Naučte se Haskell! Jestliže čtete tento úvod, je naděje, že se chcete učit Haskell. Pokud ano, jste na správném místě, ale pojďme se trochu pobavit o tomhle textu.

Rozhodl jsem se ho napsat, protože jsem chtěl utužit mé znalosti Haskellu a protože jsem si myslel, že bych mohl pomoct nováčkům naučit se Haskell z mé perspektivy. Po internetu koluje celkem málo tutoriálů na Haskell. Když jsem s Haskellem začínal, neučil jsem se pouze z jednoho zdroje. Naučil jsem se ho pročítáním několika návodů a článků, protože každý z nich vysvětloval věci jiným způsobem než ostatní. Pročtením těchto zdrojů jsem byl schopný si propojit a utříbit znalosti. Tohle je tedy pokus o přidání dalšího použitelného zdroje na naučení Haskellu a vy máte větší šanci takový zdroj najít.

pták

Návod je zaměřen na programátory, kteří mají zkušenosti s imperativními jazyky (C, C++, Java, Python…), ale nikdy neprogramovali ve funkcionálních jazycích (Haskell, ML, OCaml…). Ačkoliv bych se i vsadil, že pokud nemáte významné programátorské zkušenosti, chytrý maník jako vy bude moct sledovat příručku a naučit se Haskell.

IRC kanál #haskell (nebo #haskell.cz v češtině) na síti freenode je skvělé místo, kde se můžete ptát, pokud nebudete vědět jak dál. Lidé jsou tam nesmírně milí, trpěliví a mají pochopení pro začátečníky.

Haskell se mi nepodařilo naučit asi dvakrát, než jsem tomu konečně porozuměl, protože se mi to celé zdálo příliš divné a nechápal jsem to. Ale jednou mi to „docvaklo“ a jakmile jsem se dostal přes úvodní překážky, byla to celkem hračka. Snažím se říct, že: Haskell je skvělý a pokud se zajímáte o programování, měli byste se ho opravdu naučit, i když na začátku vypadá divně. Učit se Haskell je podobné jako se poprvé učit programovat — je to zábava! Donutí vás to myslet odlišně, což nás přivádí k další sekci…

Takže co je to Haskell?

f(x) Haskell je čistě funkcionální programovací jazyk. V imperativních jazycích se provádí věci zadáváním sekvence úloh počítači, které se pak provádí. Při provádění mohou měnit stavy. Například pokud přiřadíte proměnné a číslo 5, děláte něco dalšího, a pak změníte hodnotu proměnné na jinou. Máte k dispozici struktury pro kontrolu toku na několikanásobné provádění určitých akcí. V čistě funkcionálním programování neříkáte počítači, co má dělat, spíše mu říkáte, jaká ta věc je. Faktoriál čísla je součin všech čísel od jedničky po zadané číslo, součet seznamu čísel je první číslo plus součet všech zbylých čísel a tak dále. Tohle se vyjadřuje ve formě funkcí. Není možné také přiřadit proměnné nějakou hodnotu a poté ji změnit na něco jiného později. Pokud řeknete, že a je 5, nemůžete později říct, že je něco jiného, protože jste právě prohlásili, že je to pětka. Co jste zač, nějaký lhář? Takže v čistě funkcionálních jazycích nemá funkce vedlejší efekty. Jediná věc, co funkce může dělat, je vypočítat něco a vrátit to jako výsledek. Na první pohled to vypadá jako dost omezující, ale ve skutečnosti to má dost pěkné důsledky: pokud je funkce zavolána dvakrát se stejnými parametry, je zaručeno, že vrátí stejný výsledek. Tomu se říká referenční transparentnost a kromě zjišťování překladače o zvyklostech programátora to také umožňuje jednodušeji vyvozovat (a dokonce dokázat) správnost funkce a poté budovat složitější funkce slepováním jednoduchých funkcí k sobě.

lenost Haskell je líný. To znamená, že pokud mu nenařídíte opak, Haskell nevyhodnotí funkci a nepočítá věci, než po něm nezačnete chtít výsledek. To funguje dobře s referenční transparentností a umožňuje to považovat programy jako řadu trasformací na datech. Také to dovoluje práci s bezva věcmi jako jsou nekonečné datové struktury. Řekněme, že máme neměnitelný seznam čísel xs = [1,2,3,4,5,6,7,8] a funkci doubleMe, která vynásobí každý prvek seznamu dvojkou a poté vrátí nový seznam. Pokud chceme vynásobit náš seznam osmičkou v imperativním jazyce a udělat doubleMe(doubleMe(doubleMe(xs))), pravděpodobně by se předal seznam jedenkrát a vytvořila se kopie, která by se vrátila. Poté by se předal seznam funkci ještě dvakrát a vrátil by se výsledek. V líném jazyce se zavoláním funkce doubleMe na seznamu bez požadování výsledku skončí program zhruba tím, že si řekne: „Jo, jo, udělám to později!“ Ale pokud chcete vidět výsledek, první doubleMe řekne tomu druhému, že chce vidět výsledek, hned! Druhé řekne třetímu a třetí neochotně vrátí dvojnásobek 1, což je 2. Druhý obdrží hodnotu a vrací 4 prvnímu. První to uvidí, a zahlásí, že první prvek je 8. Takže udělá pouze jeden průchod seznamem a jenom tehdy když je to opravdu potřeba. Jedna z možností, jak chtít něco od líného jazyka, je vzít nějaká počáteční data a efektivně je transformovat a vylepšovat tak, aby se podobala našemu chtěnému výsledku.

loďka Haskell je staticky typovaný. Jakmile překládáte svůj program, překladač ví, jaký kousek kódu je číslo, jaký je řetězec a tak dále. To znamená, že hodně potenciálních chyb je odchytáno v čase překladu. Pokud se budete snažit sečíst dohromady číslo a řetězec, překladač si vám bude stěžovat. Haskell má velmi dobrý typový systém, který používá typové odvozování. To znamená, že nemusíte explicitně otypovávat každý kus kódu, protože typový systém může inteligentně přijít na hodně věcí. Pokud prohlásíte a = 5 + 4, nemusíte Haskellu říkat, že a je číslo, může na to přijít sám. Odvozování typů také dovoluje mít kód více obecný. Pokud funkce požaduje dva parametry a sečte je dohromady, není potřeba explicitně uvádět jejich typ, funkce s nimi bude pracovat jako se dvěma parametry, které se chovají jako čísla.

Haskell je elegantní a výstižný. Protože používá hodně vysokoúrovňových konceptů, programy napsané v Haskellu jsou obvykle kratší než jejich imperativní ekvivalenty. A kratší programy se jednodušeji spravují než dlouhé a obsahují méně chyb.

Haskell vytvořilo několik opravdu chytrých chlápků (s doktorskými tituly). Práce na Haskellu začala v roce 1987, kdy se vytvořil výbor výzkumníků, aby navrhli převratný jazyk. V roce 2003 byl publikován Haskell Report, který definuje ustálenou verzi jazyka.

Co bude potřeba

Textový editor a překladač Haskellu. Pravděpodobně už máte svůj oblíbený textový editor nainstalován, takže tím nebudeme ztrácet čas. Dva hlavní překladače Haskellu jsou v současnosti GHC (Glasgow Haskell Compiler) a Hugs. Pro účely tohoto tutoriálu budeme používat GHC. Nebudu se zabývat detaily instalace. Na Windows je to otázka stáhnutí instalátoru, několika kliknutí na tlačítko „Další“ a poté restartu počítače. Na linuxových distribucích postavených na Debianu stačí pouze udělat apt-get install ghc6 libghc6-mtl-dev a jste vysmátí. Nevlastním Mac, ale zaslechl jsem, že pokud máte MacPorty, můžete získat GHC provedením příkazu sudo port install ghc. Také si myslím, že se dá v Haskellu dělat vývoj pomocí té potrhlé jednotlačítkové myši, ačkoliv si nejsem jistý.

GHC umí vzít skript napsaný v Haskellu (běžně mívají příponu .hs) a přeložit jej, ale má také interaktivní mód, který umožňuje interaktivně interagovat se skripty. Interaktivně. Můžete zavolat funkci z načteného skriptu a výsledky jsou zobrazeny ihned. Pro učení je to mnohem jednodušší a rychlejší než překládat program pokaždé, když se v něm provede změna, a spouštět ho z příkazového řádku. Interaktivní mód je vyvolán napsáním ghci do příkazového řádku. Pokud máte definovány nějaké funkce v souboru, nazvaného řekněme mojefunkce.hs, načtete ho napsáním :l mojefunkce a poté si s nimi můžete hrát, pokud je soubor mojefunkce.hs ve stejném adresáři, jako bylo ghci spuštěno. Pokud ve skriptu něco změníte, stačí znovu napsat :l mojefunkce nebo příkaz :r, který je stejný, protože znovu načte současný .hs skript. Mé obvyklé pracovní prostředí, když si pohrávám s programy, je .hs soubor, ve kterém mám definovány některé funkce, jež načtu, vrtám se v něm, načtu ho znovu a tak dále. To je také, čím se zde budeme zabývat.