Ciele
- Naučiť sa používať interaktívny interpretátor GHCi.
- Naučiť sa definovať vlastné funkcie a používať ich.
- Zopakovať si rekurziu a naučiť sa definovať rekurzívne funkcie.
Postup
Krok 1: Definícia funkcií a ich aplikácia v interaktívnom interpretátore
Funkcie v jazyku Haskell sa píšu v súbore s príponou .hs. Definícia funkcie má tvar názovFunkcie parametre = výraz, napríklad:
add x y = x + y
Haskell je kompilovaný jazyk, ale existuje aj interaktívny interpretátor GHCi, ktorý umožňuje rýchlo skúšať zabudované aj vlastné funkcie. Po spustení GHCi je možné zadávať výrazy a sledovať ich výsledky.
Úloha 1.1
Vytvorte si súbor cvicenie.hs a zapíšte doň definíciu funkcie add. Načítajte tento súbor do interaktívneho interpretátora pomocou príkazu :load cesta/k/súboru.hs alebo jeho spustením s názvom súboru ako parametrom:
ghci cvicenie.hs
Skúste použiť funkciu add v interpretátore.
Krok 2: Jednoduché funkcie
Úloha 2.1
Definujte funkciu hypotenuse, ktorá vypočíta dĺžku prepony pravouhlého trojuholníka na základe dĺžok odvesien. Použite pritom funkciu sqrt na výpočet odmocniny a operátor ^ na výpočet druhej mocniny.
Poznámka
Po zmene súboru je možné ho znovu načítať pomocou príkazu :r alebo :reload.
Úloha 2.2
Definujte funkciu isLeapYear, ktorá určí, či zadaný rok je priestupný. Rok je priestupný, ak je deliteľný 4 ale zároveň nie je deliteľný 100, alebo ak je deliteľný 400. Použite bežné logické operátory a funkciu mod na zistenie deliteľnosti.
Typ funkcie isLeapYear by mohol byť:
isLeapYear :: Int -> Bool
Poznámka
Funkcie dvoch argumentov je možné používať aj ako operátory ak sa ich názov uzavrie do spätných apostrofov. Napríklad, tieto dva výrazy sú ekvivalentné:
mod 10 3
10 `mod` 3
Úloha 2.3
Definujte funkciu average pre výpočet celočíselného aritmetického priemeru zoznamu čísel. Použite pritom funkcie sum (súčet čísel), length (dĺžka zoznamu) a div pre celočíselné delenie.
listAverage :: [Int] -> Int
Krok 3: Podmienené vykonávanie
Podmienené vykonávanie je možné dosiahnuť pomocou tzv. strážcov (guards):
factorial n
| n == 1 = 1
| n >= 1 = n * factorial (n-1)
Poznámka
Telo funkcie musí byť odsadené keďže Haskell, podobne ako Python, používa odsadzovanie ako časť syntaxe.
Úloha 3.1
Definujte funkciu grade, ktorá na základe počtu bodov získaného z predmetu vráti písmenkovú známku (A, B, C, D, E, FX). V prípade neplatného vstupu, nech je výsledkom reťazec "Invalid score".
grade :: Int -> String
Úloha 3.2
Definujte funkciu ticketPrice age, ktorá na základe veku osoby vráti cenu vstupenky do kina. Štandardná cena je 8 eur, pre deti do 15 rokov a seniorov nad 65 rokov je zľava 50%.
ticketPrice :: Int -> Double
Krok 4: Rekurzia
Jedným zo spôsobov ako riešiť komplexnejšie úlohy, ktoré vyžadujú opakovanie nejakej operácie viackrát, je rekurzia.
Úloha 4.1
Definujte funkciu sumDigits, ktorá spočíta súčet číslic v zadanom celom čísle.
sumDigits :: Int -> Int
Príklad použitia:
sumDigits 123 == 6
Poznámka
Na získanie poslednej číslice čísla môžete použiť operáciu mod (modulo, zvyšok po delení), na odstránenie poslednej číslice môžete použiť celočíselné delenie div.
Úloha 4.2
Definujte funkciu isPalidrome, ktorá určí, či zadané číslo je palindróm:
isPalindrome :: Int -> Bool
isPalindrome n = n == reverseNumber n
reverseNumber n = ...
Príklady použitia:
isPalindrome 12345 == False
isPalindrome 1234321 == True
Poznámka
Definujte ďalšie pomocné funkcie podľa potreby.
Krok 5: Newtonová metóda
Na približný výpočet odmocniny je možné použiť Newtonovú metódu. Jej podstata spočíva v postupnom spresňovaní aproximácie. Ak y je odhad hodnoty druhej odmocniny čísla x, tak lepší odhad dokážeme vypočítať ako priemer čísel y a x/y.
Takže v každom kroku výpočtu je možné overiť, či odhad je už dostatočne presný, a ak nie je, vypočítať presnejší. Na overenie nám stačí vypočítať mocninu odhadu y a porovnať ju s odmocňovaným číslom x. Ich rozdiel musí byť menší ako nejaká stanovená hranica, napríklad:
$$ \left| y^2 - x \right| < 0,001 $$
Úloha 5.1
Definujte funkciu newtonSqrt pre výpočet druhej odmocniny pomocou Newtonovej metódy. Definujte si tiež pomocné funkcie
sqrtIterpre rekurzívne spresňovanie aproximácie,improvepre výpočet lepšej aproximácie,goodEnoughpre jej overenie.
Poznámka
Na výpočet absolútnej hodnoty čísla môžete použiť štandardnú funkciu abs.
Zdroje
- Simon Thompson: Haskell: the Craft of Functional Programming
- Harold Abelson, Gerald Jay Sussman: Structure and Interpretation of Computer Programs