Haskell Hero
Interaktivní učebnice pro začínající Haskellisty
|
Vyhodnocování IIOd zadání k výsledkuPříklad
Vyhodnoťte krok po kroku výraz trikrat x = x + x + x
Jak začít? Vyhodnotit první Odpověď zní: záleží na zvolené redukční strategii. Máme na výběr z následujícíh tří:
Haskell bez dalšího upřesnění vyhodnocuje líně. Vyhodnocujeme normálně
Normální redukční stratregie spočívá ve vyhodnocování zvnějšku. Řečeno konkrétněji, pokud je vyhodnocovaný výraz ve tvaru
Kratčeji: Bez ohledu na vyhodnocení argumentů aplikuj funkci Náš ukázkový výraz by se tedy podle normální strategie vyhodnotil následovně: trikrat (5 + 2) ~> (5 + 2) + (5 + 2) + (5 + 2) ~> 7 + (5 + 2) + (5 + 2) ~> 7 + 7 + (5 + 2) ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 Vyhodnocujeme striktněStriktní redukční stratregie spočívá ve vyhodnocování zevnitř. Řečeno konkrétněji, nejprve vyhodnoť argumenty na nezjednodušitelné výrazy a teprve potom aplikuj funkci. Náš ukázkový výraz by se tedy podle striktní strategie vyhodnotil následovně: trikrat (5 + 2) ~> trikrat 7 ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 Vyhodnocujeme líněLíné vyhodnocování funguje na stejném principu jako vyhodnocování normální. S tím rozdílem, že si pamatujeme výsledky vyhodnocení jednotlivých výrazů. Před každým vyhodnocením se nejdřív podíváme, jestli jsme již takový výraz někdy nevyhodnocovali. Pokud ano, použijeme výsledek z prvního vyhodnocení. Náš příklad vyhodnocený líně by tedy vypadal takto: trikrat (5 + 2) ~> (5 + 2) + (5 + 2) + (5 + 2) ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 Proč různé strategie?Vždyť se přece zdá, že striktní strategie je nejefektivnější. Nemusí se kontrolovat, zda se výraz již jednou nepočítal, a je nejrychlejší. Tak proč další dvě strategie?
Například kvůli vyhodnocení výrazu take 3 [1..] ~> take 3 ( 1: [2..] ) ~> take 3 ( 1: 2: [3..] ) ~> take 3 ( 1: 2: 3: [4..] ) ~> take 3 ( 1: 2: 3: 4: [5..] ) ~> take 3 ( 1: 2: 3: 4: 5: [6..] ) ~> take 3 ( 1: 2: 3: 4: 5: 6: [7..] ) ~> ...Výpočet by neskončil, jelikož striktní vyhodnocení požaduje úplné zjednodušení svých argumentů, což u vygenerování nekonečného seznamu, nedosáhneme. Normální strategií dospějeme k tomuto: take 3 [1..] ~> take 3 ( 1: [2..] ) ~> 1 : take 2 [2..] ~> 1 : take 2 ( 2: [3..] ) ~> 1 : 2 : take 1 [3..] ~> 1 : 2 : take 1 ( 3: [4..] ) ~> 1 : 2 : 3 : take 0 [4..] ~> 1 : 2 : 3 : []Jiným příkladem by mohlo být vyhodnocení logických výrazů. False && _ = False True && x = x ------------------------ False && ( and [True, True..] ) ~> FalsePři striktním vyhodnocování by výpočet neskončil. Normálním/líným vyhodnocením se dobereme k výsledku po jednom kroku. O línou nádstavbu jsme normální strategii doplnili proto, abychom zabránili vícenásobnému vyhodnocování stejných výrazů. |