2. diel - Prvá funkcia v Haskell
V minulej lekcii, Úvod do funkcionálního programovania , sme si ukázali, v čom by mohlo byť neprocedurálny, zvlášť potom logické programovanie užitočné. V dnešnej lekcii si už skúsime niečo napísať. Ak nemáte zatiaľ skúsenosti so žiadnym programovacím jazykom (funkcie, cykly, premenné, reťazce), potom by som odporúčal sa najskôr zoznámiť s bežným procedurálnym programovaním, aby ste mohli patrične oceniť programovania funkcionálne. Ak ste ale odvážlivci, aj tak smelo pokračujte v čítaní
Inštalácia
Najprv je potrebné si stiahnuť compiler pre jazyk Haskell. Odporúčal by
som GHC (Glasgow Haskell Compiler). Môžete si ho stiahnuť pre Windows, Linux
aj MacOS na URL adrese https://www.haskell.org/platform/.
Po inštalácii si vytvorte kdekoľvek zložku Haskell/
. Ak ste
nikdy predtým nevideli konzolu, môže to pre vás byť trochu šok, ale
otvoríme si konzolu. Na Linuxe máme priamo Terminal, v ktorom sa pomocou
príkazu cd
dostaneme do našej zložky. Ak neviete, ako s Linuxom
pracovať, odporúčam náš kurz Základy Linuxu.
Vo Windows si otvoríme Štart, napíšeme cmd
a spustíme
príkazový riadok. Napíšeme cd
, medzeru a potom pretiahneme
zložku Haskell do príkazového riadku, ako by sme kopírovali súbor:
V skutočnosti kopírujeme len cestu k súboru a tajomný príkaz
cd
znamená jednoducho Change Directory = zmeň adresár.
Teraz si spustíme GHC pomocou príkazu ghci
(GHC interactive).
Otvorí sa nám tzv. Prompt. Prelude>
vám len pomáha odsadiť
od začiatku stránky, nemá žiadny sémantický význam.
Prvý údery do klávesnice
Skúsime si konzolu ohmatať ako by to urobilo malé dieťa - jednoducho tam
niečo natlačíme a pozrieme sa, čo sa stane. Po vložení čísla sa objaví
číslo. Po vložení písmen sa objaví "not in scope", čo vo voľnom preklade
znamená - nepoznám. Ak to isté však dáme text do úvodzoviek, objaví sa
nám opäť ten istý text. Ak vložíme --
a za to nejaký text,
nestane sa nič. A po vložení (+
) na nás konzole zakričí
nejakú škaredú errorovou hlášku. Objavili sme prvý pravidlá pre písanie
v Haskell.
Funkcie, premenné, konštanty a komentáre
Zatiaľ si vystačíme s tým, že v Haskell máme tri typy "vecí".
Konštanty
Konštanta môže byť typu Int
, Float
,
Char
, String
, Boolean
atď. Ako sme
zvyknutí z iných jazykov. Preto prekladač po vložení 0
,
"0"
, '0'
a False
nebude nič
namietať.
Funkcie
Keď vložíme 5 + 3
, vyjde nám 8
. Aneb
(+)
je funkcia, ktorá berie 2 argumenty a vracia jeden.
Premenné
Tretím typom konštrukcií jazyka Haskell sú premenné, ktoré začínajú
malým písmenom, alebo podčiarknikom. Napíšme si let dva = 2
.
Potom kedykoľvek napíšeme dva
, zobrazí sa 2
.
Slovko let
je niečo ako interaktívny priradenie do premennej či
do funkcie.
Kalkulačka
Čo sa týka kalkulácií, Haskell vie precízne pracovať s veľkými
číslami. Skúsme si treba napísať 123456789^12345
. To žiadna
kalkulačka bez protestov nevezme.
"Kalkulačka" v konzole vie tieto operácie:
((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áre
Sekvencia --
v texte vyššie sú samozrejme komentáre,
poznámky pre programátora, ktorých si Haskell nevšíma.
Funkcie
Kalkulačka nás na 15 sekúnd zabavia, ale čoskoro to začne byť nuda. Tak
sa preto pozrime na niečo lepšie. Funkcia je v Haskell stavebný kameň
všetkého. Aj vloženie 5
je vlastne funkcia identita na
5
. Skúsme si to. Napíšme 5
a potom skúsme
napísať id 5
. Výsledok je ten istý. Téma funkciou je natoľko
dôležité, že mu budeme venovať zvyšok dnešnej lekcie.
Funkcia je niečo ako tajomná škatuľka s jednou alebo viacerými
vstupnými premennými a jedným výstupom. Funkcia musí mať výstup a to
práve jeden. Spoznali sme už funkciu identity, čo je v podstate taká rúra.
Čo vložíte, to aj vypadne von. Skúsme si napísať sami zložitejšie
funkciu inc
, ktorá zoberie číslo a zvýši ho o jedna.
let inc x = x + 1
. Slovko let
už poznáme, je to
interaktívne príkaz priradenia. inc
je názov funkcie,
x
je jej parameter. Táto funkcia robí presne to, čo jej
napíšeme. Akonáhle dostane x
, vráti x + 1
. Skúste
si teraz sami napísať funkciu vynasob2
a vrat0
.
Prvé vynásobí číslo 2
, druhá funkcia vráti 0
na
čokoľvek, čo jej pošlete. Keď už máme funkciu zadefinované, volanie je
jednoduché: inc 4
a kompiler odpovie 5
.
Skladanie funkcií
Čo by to bolo ale za svet, keby sme nemohli použiť stavebnicu z malých
funkcií, ktoré sme si už napísali. Skúsme si teraz napísať funkciu,
ktorá zvýši premennú o 2
, čiže inc2
:
let inc2 x = inc ( inc x) let inc2 x = inc $ inc x
Oba zápisy sú ekvivalentné, znak $
supluje zátvorky až do
konca riadku. Časom uvidíme, že používanie dolára je veľmi praktické,
ale zátvorky rozhodne nikomu vadiť nebudú. Čo sa vlastne pri spájaní
funkcií deje? Najlepšie si to predstavíme ako vlak. Niečo vložíme do
jedného vagónu, on s tým niečo urobí, pošle to ďalej atd ... Uvedomme si,
že nemá zmysel hovoriť o funkciách s rovnakým slovníkom ako napr. V Jave či v C ++. Nejaké
odovzdávanie hodnotou? Odkazom? private
, public
,
static
... Funkcie v Haskell fungujú úplne inak.
Funkcia tu nemajú žiadne vedľajšie efekty. Tzn. niečo do nich pošleme, niečo z nich vyjde. Pošleme do nich to isté a vyjde z nich to isté. Odpadajú starosti s tým, že čítame z nejakej premennej, ale iné vlákno do nej pred chvíľou zapísalo, ale my sme si to neošetrili a ono ... Nie, nič také v Haskell nie je. Haskell sa preto veľmi hodí na paralelné spracovanie, pretože jednoducho nemá žiadne vedľajšie efekty. Napriek tomu sú niekde potreba a časom sa naučíme ako niečo ako vedľajší efekt do Haskell prepašovať, ale to nám bude ešte chvíľu trvať. Pre precvičenie si môžete skúsiť napísať pár funkcií do nabudúce:
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ženie do súboru
Keď už máme veľa funkcií, je trochu ťažké si ich všetky pamätať a
bolo by dobré si ich niekam uložiť, napríklad do súboru
prvni.hs
. Je dôležité priradiť súboru príponu
.hs
, lebo tak kompilátor spozná, že ide o Haskell source. Buď
môžete priamo v konzole napísať :e muj.hs
a objaví sa vám vo
Windows poznámkový blok, v Linuxe pravdepodobne nano, alebo môžete rovno
otvoriť editor a uložiť súbor pod menom prvni.hs
. Pre Windows
je poznámkový blok ideálne, pre Linux si môžete nastaviť napríklad vim
pomocou :set editor vim
. Do súboru prvni.hs
si
uložte všetky funkcie, ktoré sme si dnes definovali a potom sa vráťte do
ghci. V ňom zadajte :l prvni.hs
alebo :load prvni.hs
a mala by sa vám objaviť hláška "OK, modules load". Teraz, ak zmeníte
niečo vo svojom zdrojovom súbore, stačí do ghci napísať len
:r
ako reload a máte opäť načítané. Vo výsledku je teda
veľmi pohodlné programovať napríklad takto:
Nabudúce, v lekcii Haskell - Teba by som typoval na funkciu ... , sa pustíme už do zaujímavejších funkcií a dátových štruktúr. Tak sa tešte. Riešenie k príkladom prikladám v haskellovském zdrojáky.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 529x (111 B)