Lekce 2 - První funkce v Haskell
V minulé lekci, Úvod do funkcionálního programování, jsme si ukázali, v čem by mohlo být
neprocedurální, zvláště pak logické programování užitečné. V dnešní
lekci si již zkusíme něco napsat. Pokud nemáte zatím zkušenosti s
žádným programovacím jazykem (funkce, cykly, proměnné, řetězce), pak
bych doporučoval se nejdříve seznámit s běžným procedurálním
programováním, abyste mohli patřičně ocenit programování funkcionální.
Jste-li ale odvážlivci, i tak směle pokračujte ve čtení
Instalace
Prvně je třeba si stáhnout compiler pro jazyk Haskell. Doporučoval bych
GHC (Glasgow Haskell Compiler). Můžete si ho stáhnout pro Windows, Linux i
MacOS na URL adrese https://www.haskell.org/platform/.
Po instalaci si vytvořte kdekoliv složku Haskell/
. Pokud jste
nikdy předtím neviděli konzoli, může to pro vás být trochu šok, ale
otevřeme si konzoli. Na Linuxu máme přímo Terminal, ve kterém se pomocí
příkazu cd
dostaneme do naší složky. Pokud nevíte, jak s
Linuxem pracovat, doporučuji náš kurz Základy
Linuxu. Ve Windows si otevřeme Start, napíšeme cmd
a
spustíme příkazovou řádku. Napíšeme cd
, mezeru a pak
přetáhneme složku Haskell do příkazového řádku, jako bychom kopírovali
soubor:

Ve skutečnosti kopírujeme jen cestu k souboru a tajemný příkaz
cd
znamená prostě Change Directory = změň adresář.
Nyní si spustíme GHC pomocí příkazu ghci
(GHC interactive).
Otevře se nám tzv. prompt. Prelude>
vám jen pomáhá odsadit
od začátku stránky, nemá žádný sémantický význam.

První údery do klávesnice
Zkusíme si konzoli osahat jako by to udělalo malé dítě - jednoduše tam
něco namačkáme a podíváme se, co se stane. Po vložení čísla se objeví
číslo. Po vložení písmen se objeví "not in scope", což ve volném
překladu znamená – neznám. Pokud to samé však dáme text do uvozovek,
objeví se nám opět ten samý text. Pokud vložíme --
a za to
nějaký text, nestane se nic. A po vložení (+
) na nás konzole
zakřičí nějakou ošklivou errorovou hlášku. Objevili jsme první pravidla
pro psaní v Haskell.
Funkce, proměnné, konstanty a komentáře
Prozatím si vystačíme s tím, že v Haskell máme tři typy "věcí".
Konstanty
Konstanta může být typu Int
, Float
,
Char
, String
, Boolean
atd. Jak jsme
zvyklí z jiných jazyků. Proto překladač po vložení 0
,
"0"
, '0'
a False
nebude nic namítat.
Funkce
Když vložíme 5 + 3
, vyjede nám 8
. Aneb
(+)
je funkce, která bere 2 argumenty a vrací jeden.
Proměnné
Třetím typem konstrukcí jazyka Haskell jsou proměnné, které začínají
malým písmenem, nebo podtržítkem. Napišme si let dva = 2
.
Potom kdykoliv napíšeme dva
, zobrazí se 2
. Slůvko
let
je něco jako interaktivní přiřazení do proměnné či do
funkce.
Kalkulačka
Co se týká kalkulací, Haskell umí precizně pracovat s velkými čísly.
Zkusme si třeba napsat 123456789^12345
. To žádná kalkulačka
bez protestů nevezme.
"Kalkulačka" v konzoli umí tyto operace:
((2+5 - 49*100 )/ 3^2 ) * (-5) -- záporná čísla musí být v závorkách "ahooj" ++ " svete!" -- spojování stringů True && True -- logické and True || False -- logické or not True -- negace 1==0 -- rovnost 1/=0 -- nerovnost
Komentáře
Sekvence --
v textu výše jsou samozřejmě komentáře,
poznámky pro programátora, kterých si Haskell nevšímá.
Funkce
Kalkulačka nás na 15 sekund zabaví, ale brzy to začne být nuda. Tak se
proto podívejme na něco lepšího. Funkce je v Haskell stavební kámen
všeho. I vložení 5
je vlastně funkce identita na
5
. Zkusme si to. Napišme 5
a pak zkusme napsat
id 5
. Výsledek je ten samý. Téma funkcí je natolik důležité,
že mu budeme věnovat zbytek dnešní lekce.
Funkce je něco jako tajemná krabička s jednou nebo více vstupními
proměnnými a jedním výstupem. Funkce musí mít výstup a to právě jeden.
Poznali jsme už funkci identity, což je v podstatě taková roura. Co
vložíte, to i vypadne ven. Zkusme si napsat sami složitější funkci
inc
, která vezme číslo a zvýší ho o jedna.
let inc x = x + 1
. Slůvko let
již známe, je to
interaktivní příkaz přiřazení. inc
je název funkce,
x
je její parametr. Tato funkce dělá přesně to, co jí
napíšeme. Jakmile dostane x
, vrátí x + 1
. Zkuste
si nyní sami napsat funkci vynasob2
a vrat0
. První
vynásobí číslo 2
, druhá funkce vrátí 0
na
cokoliv, co jí pošlete. Když již máme funkci zadefinovanou, volání je
snadné: inc 4
a kompiler odpoví 5
.
Skládání funkcí
Co by to bylo ale za svět, kdybychom nemohli použít stavebnici z malých
funkcí, které jsme si již napsali. Zkusme si nyní napsat funkci, která
zvýší proměnnou o 2
, neboli inc2
:
let inc2 x = inc ( inc x) let inc2 x = inc $ inc x
Oba zápisy jsou ekvivalentní, znak $
supluje závorky až do
konce řádku. Časem uvidíme, že používání dolaru je velmi praktické,
ale závorky rozhodně nikomu vadit nebudou. Co se vlastně při spojování
funkcí děje? Nejlépe si to představíme jako vlak. Něco vložíme do
jednoho vagónu, on s tím něco udělá, pošle to dále atd... Uvědomme si,
že nemá smysl mluvit o funkcích se stejným slovníkem jako např. v Javě či v C++. Nějaké
předávání hodnotou? Odkazem? private
, public
,
static
... Funkce v Haskellu fungují úplně jinak.
Funkce zde nemají žádné vedlejší efekty. Tzn. něco do nich pošleme, něco z nich vyjde. Pošleme do nich to samé a vyjde z nich to samé. Odpadají starosti s tím, že čteme z nějaké proměnné, ale jiné vlákno do ní před chvílí zapsalo, ale my jsme si to neošetřili a ono... Ne, nic takového v Haskellu není. Haskell se proto velmi hodí na paralelní zpracování, protože prostě nemá žádné vedlejší efekty. Přesto jsou někde potřeba a časem se naučíme jak něco jako vedlejší efekt do Haskellu propašovat, ale to nám bude ještě chvíli trvat. Pro procvičení si můžete zkusit napsat pár funkcí do příště:
vynasob3 x y z -- funkce vynásobí 3 čísla zalziMi x -- funkce dostane boolean, třeba zalziMi (3 == 5) a řekne pravý opak. (z True na False a obráceně), parametr musíte zadat v závorkách a i když i v Haskellu jde napsat if, vystačíte si nádherně bez něj. dec x -- sníží x o jedna
Uložení do souboru
Když již máme hodně funkcí, je trochu obtížné si je všechny
pamatovat a bylo by dobré si je někam uložit, třeba do souboru
prvni.hs
. Je důležité přiřadit souboru příponu
.hs
, neboť tak kompilátor pozná, že jde o Haskell source. Buď
můžete přímo v konzoli napsat :e muj.hs
a objeví se vám ve
Windows poznámkový blok, v Linuxu nejspíše nano, nebo můžete rovnou
otevřít editor a uložit soubor pod jménem prvni.hs
. Pro Windows
je poznámkový blok ideální, pro Linux si můžete nastavit třeba vim
pomocí :set editor vim
. Do souboru prvni.hs
si
uložte všechny funkce, které jsme si dnes definovali a potom se vraťte do
ghci. V něm zadejte :l prvni.hs
nebo :load prvni.hs
a
měla by se vám objevit hláška "OK, modules load". Nyní, pokud změníte
něco ve svém zdrojovém souboru, stačí do ghci napsat jen :r
jako reload a máte opět načteno. Ve výsledku je tedy velmi pohodlné
programovat třeba takto:

Příště, v lekci Haskell - Tebe bych typoval na funkci..., se pustíme již do zajímavějších funkcí a datových struktur. Tak se těšte. Řešení k příkladům přikládám v haskellovském zdrojáku.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkamiStaženo 602x (111 B)