Funkcionální programování - Výrazy a definice
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Funkcionální programování - Výrazy a definiceFunkcionální programování - Výrazy a definice

 

Funkcionální programování - Výrazy a definice

Google       Google       4. 5. 2006       18 137×

V seriálu o funkcionálním programování pokračujeme druhou částí, ve které si všimneme základních elementů, z nichž se skládají funkcionální programy.

Výrazy se skládají zejména z funkcí aplikovaných na argumenty. Jak funkce, tak argumenty, jsou vyjádřeny jinými podvýrazy.

Funkce a operátory

Základní způsob, jak vytvářet složitější výrazy z jednodušších, je aplikace funkce na argumenty. Aplikaci funkce f na argumenty x, y, z zapisujeme:


f x y z

Obecně mohou na místě argumentů i funkce stát libovolné výrazy. Pokud je argumentem proměnná, není nutno ji uzavírat do závorek.

V mnoha jazycích, jako třeba C nebo Java, se rozlišuje mezi uživatelsky definovanými funkcemi, pojmenovanými identifikátorem, a mezi operátory, pojmenovanými zvláštním symbolem (+, *, &&, ||) a s infixovou syntaxí pro aplikaci takových operátorů na argumenty. Moderní funkcionální jazyky umožňují uživatelské definice funkcí i operátorů.

V souladu s terminologií jazyka Haskell budeme operátorem nazývat binární funkci, jejíž jméno nezačíná písmenem. Například (+), (-), (*), (/), (^) budou běžné aritmetické operátory, (==), (/=), (<), (<=), (>), (>=) relační operátory, a (&&), (||) booleovské operátory.

Uvedený prefixový tvar aplikace však není vždy pohodlný. Proto v případě binárních operátorů budeme kromě prefixového zápisu aplikace


(+) x y

používat též infixový zápis


x + y

Navíc, u asociativních binárních operátorů můžeme vynechávat nadbytečné závorky a využívat obvyklých priorit, takže třeba


(+) ((*) ((*) 1 2) 3) ((*) 3 4)

lze zapsat přehledněji:


1 * 2 * 3  +  3 * 4

Prefixově zapsaná aplikace má při výpočtu přednost před infixovou: f x+y je totéž jako (f x) + y.

Všimněme si, že odkazujeme-li se na operátory samostatně (např. vystupují-li ve výrazu jako argumenty vyšších funkcí apod.), uvádíme je v kulatých závorkách. V infixově zapisované aplikaci je uvádíme bez závorek. Naopak binární funkce (jejich jméno je alfanumerické a začíná malým písmenem) uvádíme bez závorek a jejich aplikaci píšeme obvykle prefixově. Při alternativním infixovém zápisu je uvádíme v obrácených apostrofech.


21  `lcm`  6
lcm  14    21
2006 `mod` 491
mod  1992  50

Lokální­ definice

Kdybychom byli při vytváření výrazů odkázáni pouze na pevně danou malou množinu konstant a funkcí, byly by naše vyjadřovací schopnosti silně omezené. Proto téměř všechny jazyky umožňují definovat nové konstanty a funkce.

Jestliže chceme ve výrazu použít nějaký podvýraz vícekrát, např.:


(pi/2) * x  +  (pi/2) * y

můžeme v něm lokálně zavést novou proměnnou d:


let  d = pi/2  in  d * x  +  d * y

Části výrazu mezi let a in říkáme definice.

Nově definované proměnné (nalevo od rovnítka) jsou vázány na výrazy (napravo od rovnítka) a jsou použitelné v části výrazu za in. Těchto lokálních definic může být v rámci jednoho výrazu let i více naráz a mohou být použity i na pravých stranách definic:


let  a = 3
     b = 4
     c = 5
     s = (a+b+c)/2
in  s*(s-a)*(s-b)*(s-c)

Alternativně můžeme lokální definice zapisovat pomocí konstrukce where. Ta se od výrazu let liší tím, že lokální definice je uvedena až za výrazem, v němž je použita.


f x y  =  d * x  +  d * y  where  d = pi/2

p s  =  s*(s-a)*(s-b)*(s-c)  where  s = (a+b+c)/2

Druhý rozdíl spočívá v tom, že konstrukce where může stát jen v nadřazené definici, zatímco let je výraz a může být tedy podvýrazem libovolného výrazu.

Definovat můžeme i funkci. Kromě jejího jména zapíšeme nalevo od definičního rovnítka i její parametry, což budou (v nejjednodušším případě) jména proměnných:


cube x  =  x * x * x
max3 a b c  =  max a (max b c)
u .-. v  =  if u>v then u-v else 0

Poslední řádek definuje operátor (.-.). Ekvivalentní způsob zápisu je


(.-.) u v  =  if u>v then u-v else 0

Podstatným důvodem, proč definice zvyšují naši vyjadřovací sílu, je fakt, že definice mohou být rekursivní:


fact n  =  if n==0 then 1 else n*fact(n-1)
a ^^^ n  =  if n==0 then 1 else a*(a^^^(n-1))

Globální definice a skripty

Řekli jsme, že definice za slovem where mají jen lokální působnost – vztahují se pouze na podvýraz před where. Často bývá pohodlné definovat si nové funkce i globálně – pro všechny výrazy, s nimiž pracujeme v programu. Proto je v Haskellu také možnost definovat konstanty a funkce i globálně. Definice se zapíší do zvláštního souboru – skriptu.

Například napíšeme-li do souboru priklad.hs definici faktoriálu


fact n  =  if n==0 then 1 else n*fact(n-1)

a spustíme interpret pomocí hugs priklad.hs, můžeme pak ve svých výrazech funkci fact používat.

Definice podle vzoru

Na místě formálních parametrů funkcí a operátorů nemusejí vystupovat jen proměnné. Obecně zde jsou tzv. vzory. Vzor popisuje množinu argumentů, které tomuto vzoru „vyhovují“. Definice funkce se pak rozpadá na více větví, klausulí. Při výpočtu se pak z definice použije ta větev, jejíž vzory vyhovují skutečným argumentům. Například výše uvedenou definici funkce fact lze pomocí vzorů zapsat takto:


fact 0  =  1
fact n  =  n * fact(n-1)

Častým vzorem, jak je vidět z těchto příkladů, je konstanta. Takový vzor vyhovuje pouze jedinému skutečnému argumentu – tomu, jenž je roven právě této konstantě. V tomto příkladě to je 0 v prvním řádku definice. Naopak vzor, kterým je proměnná, vyhovuje všem argumentům. To je případ druhého řádku definice. V našem příkladě případ, že argument funkce fact je nulový, vyhovuje oběma řádkům definice. Proto, aby taková definice byla korektní, dohodneme se, že se při výpočtu použije vždy první větev definice, jejíž vzory vyhovují skutečným argumentům funkce. V uvedeném příkladě se tedy první větev definice bere pro nulový argument a druhá větev pro všechny ostatní, tedy nenulové argumenty.

Podobně funkci sumsq pro výpočet součtu čtverců (z úvodní části) lze zapsat i takto:


sumsq 1  =  1
sumsq n  =  n*n + sumsq (n-1)

Jiným příkladem mohou být definice booleovských operátorů, v nichž vzory jsou opět booleovské konstanty nebo proměnné.


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

False || x  =  x
True  || x  =  True

not True   =  False
not False  =  True

Vzory však nemusejí být jen konstanty a proměnné. Obecněji je vzor výraz, jehož žádný podvýraz nelze redukovat – skládá se pouze z proměnných a tzv. konstruktorů. Konstanty jsou vlastně nejjednoduššími konstruktory – jsou to konstruktory arity 0. Konstruktorem arity 2, tedy binárním konstruktorem, je například konstruktor (,) uspořádaných dvojic. Můžeme ho využít třeba v haskellovských definicích:


fst (x,y) = x
snd (x,y) = y

Další konstruktory poznáme v části o datových strukturách.

Shrnutí

  • Výrazy se skládají z aplikací funkcí a operátorů na argumenty a z lokálních definic.
  • Globální definice zavádějí nové funkce a konstanty, které pak platí ve všech použitých výrazech.
  • Definice mohou být rekursivní.
  • Funkce lze definovat pomocí vzorů – výrazů popisujících možné tvary skutečných argumentů.

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

2 názory  —  2 nové  
Hlasování bylo ukončeno    
0 hlasů
Google
Autor je profesorem na Fakultě informatiky Masarykovy univerzity v Brně.

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý