Haskell Hero

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

Funkce nad Bool

Proč funkce nad hodnotami Bool?

Příklad

Definujte funkci velkeSude :: Integer -> Char, kde výraz velkeSude x se vyhodnotí na znak 'A', pokud je x sudé a zároveň větší než 10, a na znak 'N' v opačném případě.


Řešení, které by nás napadlo asi jako první, by bylo nejspíše následující:

  • Zjisti, zda je x sudé.
    • Pokud ano, zjisti, zda je x větší než 10.
      • Pokud ano, vyhodnoť výraz na 'A'.
      • Pokud ne, vyhodnoť výraz na 'N'.
    • Pokud ne, vyhodnoť výraz na 'N'.

Zapsáno v Haskellu:

velkeSude   ::  Integer -> Char
velkeSude x  =  if even x then if x > 10 then 'A'
                                         else 'N'
                          else 'N'
Asi nemá cenu zdůrazňovat, že kdyby byly podmínky tři nebo čtyři a požadovali bychom, aby byly všechny splněny, kód by se stal velice nepřehledným. Proto máme funkce nad hodnotami Bool.

A zároveň

A zároveň, neboli logická konjunkce je binární funkce zapisovaná operátorem (&&). Jako argumenty si bere dvě hodnoty typu Bool. Výraz x && y se vyhodnotí na True, pokud jsou True i obě hodnoty x a y.

Definice

(&&)         ::  Bool -> Bool -> Bool
True && True  =  True
_    && _     =  False
Tato definice předpokládá, že již známe vyhodnocené hodnoty obou argumentů. Pokud se ale první argument vyhodnotí na False, nemusíme už druhý argument vůbec vyhodnocovat, protože ať je jeho hodnota jakákoli, výsledná hodnota bude opět False.

Naopak, pokud se první argument vyhodnotí na True, pak se celý výraz vyhodnotí na výsledek vyhodnocení druhého argumentu.

Proto se používá definice následující:

False && _  =  False
True  && x  =  x

Příklad

Vezměme si ukázkový příklad z prvního odstavce. Jeho definice pomocí (&&) by mohla vypadat následovně:

velkeSude x  =  if  even x  &&  x > 10  then 'A'
                                        else 'N'

Nebo

Funkci nebo, neboli logickou disjunkci použijeme tehdy, pokud chceme vytvořit složenou podmínku, která má uspět, pokud je alespoň jedna vnitřní podmínka splněna. Zapisuje se dvěma svislítky: (||).

Definice

False || False  =  False
_     || _      =  True
Podobně jako funkce (&&) má i funkce (||) efektivnější variantu. Pokud se totiž první argument vyhodnotí na True, nepotřebujeme už znát hodnotu druhého argumentu. Neboť již v této chvíli víme, že se celý výraz vyhodnotí na True.
True  || _  =  True
False || x  =  x

Příklad

Definujte funkci mezi :: Integer -> String, kde se výraz mezi x vyhodnotí na "Ano", pokud je x celé číslo mimo hodnoty 10 až 20, a na "Ne" v opačném případě.


Definujeme tedy funkci, která otestuje, zda je číslo menší jak 10 nebo větší jak 20.

mezi   ::  Integer -> String
mezi x  =  if  x < 10  ||  x > 20  then  "Ano"
                                   else  "Ne"

Not

Unární funkce not nedělá nic jiného, než logickou negaci.

Definice

not       ::  Bool -> Bool
not True   =  False
not False  =  True