Ciele
- Naučiť sa používať interaktívny interpretátor GHCi.
- Naučiť sa definovať vlastné funkcie a používať ich.
- Oboznámiť sa s koncepciou typov v jazyku Haskell.
Postup
Krok 1: GHCi
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.
Haskell podporuje bežné infixné operátory, napríklad:
1 + 2
2 * (5^2 - 4)
(4 <= 2) && (4 /= 2)
"hello" == "hello"
Aplikácia funkcie sa zapisuje bez zátvoriek okolo argumentov. Argumenty sú oddelené len medzerou. Napríklad:
max 4 2
sin (pi / 2)
sin pi / 2 == (sin pi) / 2
Úloha 1.1
Napíšte výraz, ktorý vypočíta dĺžku prepony pravouhlého trojuholníka s odvesnami dĺžky 3 a 4. Použite pritom funkciu sqrt
.
Krok 2: Vlastné funkcie
Vlastné funkcie 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
Úloha 2.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 pomocou tlačidla na otvorenie súboru vo WinGHCi. Skúste použiť funkciu add v interpretátore.
Úloha 2.2
Definujte funkciu hypotenuse, ktorá vypočíta dĺžku prepony pravouhlého trojuholníka na základe dĺžok odvesien.
Poznámka
Po zmene súboru je možné ho znovu načítať pomocou príkazu :r
alebo :reload
.
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 2.3
Definujte funkciu middleNumber, ktorá vráti stredné z troch zadaných čísel:
middleNumber :: Integer -> Integer -> Integer -> Integer
Príklady použitia:
middleNumber 5 3 8 == 5
middleNumber 1 1 1 == 1
Úloha 2.4
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: Typy
Haskell má statickú typovú kontrolu, ale vo väčšine prípadov nie je nutné uvádzať typy explicitne. Prekladač dokáže automaticky odvodiť typy hodnôt a funkcií. Odvodený typ je možné pozrieť v GHCi pomocou špeciálneho príkazu :t
, napríklad:
:t 'a'
:t 5
:t not
:t sqrt
:t max
Úloha 3.1
Skontrolujte typy vašich funkcií hypotenuse
a factorial
.
Typ funkcie môžeme deklarovať ak explicitne, napríklad:
add :: Integer -> Integer -> Integer
add x y = x + y
Úloha 3.2
Definujte typ funkcie factorial
ako Int -> Int
a použite ju na výpočet faktoriálu čísla 21. Zmeňte typ na Integer -> Integer
a vyskúšajte to znovu.
Poznámka
Na konverziu medzi typmi Int
a Integer
je možné použiť funkcie fromInteger
a toInteger
.
Krok 4: Viac funkcií
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 4.1
Definujte funkciu newtonSqrt
pre výpočet druhej odmocniny pomocou Newtonovej metódy. Definujte si tiež pomocné funkcie
sqrtIter
pre rekurzívne spresňovanie aproximácie,improve
pre výpočet lepšej aproximácie,goodEnough
pre 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