Haskell Hero

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

Výrazy

Co je to výraz?

Výraz je všechno, co nám Hugs bez připomínky vezme a není to povel.

5 + 2 je výraz.

7 je výraz.

"Haskell" je výraz.

'c' je výraz.

even 5 je výraz.

V krabičkové metodě budeme výrazy znázorňovat různými geometrickými tělesy (válec, hranol, těšit se můžete i na vláček). Bude vysvětleno později.


Znázornění výrazů pomocí krabiček

Prefixový / infixový zápis

V Haskellu používáme dva typy zápisu výrazů. Prefixový a infixový. Ukázka na začátek:

Infixový zápis: 3 + 5


Infixový zápis

Prefixový zápis: div 8 3


Prefixový zápis

3 + 5 čteme [tři plus pět]

div 8 3 čteme [aplikace funkce div na argumenty 8 a 3]

Znaménko označující unární či binární funkci, se někdy nazývá operátor. Rozlišujeme dva druhy operátorů:

  • alfanumerický skládající se z písmen a číslic, např. funkce div a mod
  • nealfanumerický +,^.

Každý infixově zapsaný výraz můžeme zapsat prefixově. Opačně to funguje pouze u binárních funkcí.

Infixově zapsaný výraz za použití nealfanumerického operátoru převedeme do prefixu tak, že operátor dáme do závorek a napíšeme jej před argumenty.

3 + 5  ==>  (+) 3 5

Prefixově zapsaný výraz alfanumerickým operátorem zapíšeme infixově tak, že operátor obalíme zpětnými apostrofy a vložíme jej mezi argumenty.

div 8 3  ==>  8 `div` 3

Mezi infixovým a prefixovým zápisem není žádný výpočetní rozdíl. Vyzkoušejte si sami v Hugsu. Oba jsou zpracovány stejně, akorát prefixově zapsaná funkce má větší prioritu. To znamená, že ve výrazu

3 * div 5 2
se nejdříve provede prefixově zapsané celočíselné dělení a teprve potom infixově zapsané násobení.

Podvýrazy

Každý výraz se dá rozložit na podvýrazy. Ukázkový výraz: 3 + 5

Pro snazší rozložení výrazu na podvýrazy převedeme výraz do prefixového tvaru.
(+) 3 5

Podvýrazem je:

  • funkce a její argumenty (+) 3 5, což jsou tři podvýrazy

  • funkce a její 1 argument, funkce a její 2 argumenty, … , funkce a jejích n argumentů
    (+) 3 5
    (+) 3 5
Výraz 3 + 5 má celkem 5 podvýrazů.


Složitější výraz: (zipWith (*) [1,2] [3,4]) ++ [5,6]

  • převedeme do prefixu:
    (++) (zipWith (*) [1,2] [3,4]) [5,6]

  • funkce (++) a její dva argumenty, celkem 3 podvýrazy
    (++) (zipWith (*) [1,2] [3,4]) [5,6]

  • funkce (++) a její první argument, 1 podvýraz
    (++) (zipWith (*) [1,2] [3,4]) [5,6]

  • funkce (++) a její první dva argumenty, což je celý výraz, 1 podvýraz
    (++) (zipWith (*) [1,2] [3,4]) [5,6]

  • funkce (++) a její argument [5,6] už jsou dále nerozložitelné, budeme rozkládat podvýraz
    zipWith (*) [1,2] [3,4]:

    • funkce zipWith a její tři argumenty, 4 podvýrazy
      zipWith (*) [1,2] [3,4]

    • funkce zipWith a její první argument, 1 podvýraz
      zipWith (*) [1,2] [3,4]

    • funkce zipWith a její první dva argumenty, 1 podvýraz
      zipWith (*) [1,2] [3,4]

    • funkce zipWith a její první tři argumenty, což je celý výraz, který jsme už jako podvýraz započítali v druhém kroku

Výraz (zipWith (*) [1,2] [3,4]) ++ [5,6] má tedy 11 podvýrazů.