Haskell Hero

Interaktivní učebnice pro začínající Haskellisty

Vyhodnocování

Co je vyhodnocování

Funkcionální programování se celé točí okolo vyhodnocování výrazů. Uvědomme si, že už ve chvíli, kdy zadáváme Hugsu výraz k vyhodnocení, mu zadáváme výsledek výpočtu v určitém tvaru. Hugs tento nějakým-způsobem-zapsaný-výsledek vezme a převede jej do tvaru, který už se nedá dále zjednodušit.

Například 3 + 5 je výraz, který se dá zjednodušit na dále nezjednodušitelný výraz 8. Takové zjednodušení označujeme vlnitou šipkou ~>. Zjednodušení předchozího výrazu bychom tedy zapsali 3 + 5 ~> 8.

Vyhodnocujeme

Všechny výrazy se samozřejmě nevyhodnotí po jednom kroku. Například vyhodnocení výrazu 3 + 5 * 2 na nezjednodušitelný tvar se provede ve dvou krocích:

3 + 5 * 2  ~>  3 + 10  ~>  13

Pokud chceme zapsat, že se výraz zjednodušil na jiný výraz ve dvou krocích, ale nechceme uvádět mezikrok, napíšeme

3 + 5 * 2  ~>²  13

Stejně bychom postupovali, pokud bychom chtěli napsat, že se výraz zjednodušil na jiný po třech krocích:

3 * 4 + 2 * 5  ~>³  22
atd.

Pokud chceme zapsat, že se výraz zjednodušil na jiný a je nám jedno, kolik kroků zjednodušování zabralo, napíšeme nad šipku místo čísla hvězdičku: ~>*.

Priorita operátorů, směr sdružování

Nabízí se otázka „Jakto, že při vyhodnocování výrazu 3 + 5 * 2 Hugs ví, že násobení má přednost před sčítáním? Je to jednoduché. Hugs se totiž řídí podle následující tabulky, která určuje, která operace má přednost před kterou. Čím má operace vyšší prioritu, tím dříve se provede.

Sčítání má prioritu 6, násobení 7, což znamená, že se násobení provede před sčítáním. Předchozí výraz by se tedy vyhodnotil

3 + 5 * 2  ~>  3 + 10  ~>  13

Pokud chceme vynutit, aby se sčítání provedlo před násobením, dáme 3 + 5 do závorky: (3 + 5) * 2

Prefixový zápis má vždy přednost před infixovým. Ve výrazu (+) 3 5 * 2 se nejdříve vyhodnotí sčítání a až poté násobení.

(+) 3 5 * 5 ~> 8 * 5 ~> 40

Dále by nás mohlo zajímat, zda se má výraz 3 ^ 3 ^ 3 vyhodnotit jako 3 ^ (3 ^ 3), nebo jako (3 ^ 3) ^ 3. I tento problém řeší následující tabulka. Konkrétně sloupec Směr sdružování. Umocňování sdružuje zprava doleva, tzn. předchozí výraz by se vyhodnotil jako 3 ^ 3 ^ 3 ~> 3 ^ 27 ~> 7625597484987.

Priorita Směr sdružování Operátory
9 .
9 !!
8 ^
7 * / `div` `mod`
6 + -
5 : ++
4 == /= < <= > >= `elem` `notElem`
3 &&
2 ||