Az ML-ben a függvények maguk is értékek. Mégpedig egyváltozósak, de ez a változó lehet egy rendezett n-es vagy akár egy leképezés(függvény) is. A képe pedig n-es vagy függvény. Az előzőek miatt a függvényeket a Curry féle jelölésmódban kell definiálni és használni.
Egy függvényt a fun kulcsszó segítségével definiálhatunk.
fun < fun_name > < parameter > = < expression > [ | < fun_name > < parameter > = < expression > ];
vagy fun nélkül :
val < fun_name > = fn < parameter > => < expression> [ | < parameter > => < expression > ];
Példák:
Ezeket a függvényeket egyszerűen a beírásukkal definiáltuk. Ahhoz, hogy egy függvényt végrehajtsunk, egyszerűen adjuk meg a nevét, utána pedig az aktuális paramétereket. Például:
A fenti kifejezésekre a rendszernek a következő értékeket kell visszaadnia: 12 : int, 101 : int, "tuba" : string.
Definiáljuk a "double" egyszerű függvényt a következőképpen:
A függvényt kipróbálhatjuk, úgy, hogy egy kiértékelhető kifejezést teszünk az argumentumába, pl.:
A "times4" függvényt elkészíthetjük a "double" kétszeri alkalmazásával, ezt hívjuk függvénykompozíciónak:
A több mint egy bemenettel rendelkező függvényeket rendezett n -esekkel (tuple) definiálhatjuk. Például definiálhatjuk az "aveI" -t és az "aveR" -t a következőképpen:
Megfigyelhetjük, hogy az ML maga "találja ki" az egyes függények típusát.
Egy egynél több bemenettel rendelkező függvényt implementálhatunk rendezett n -esek (tuple) segítségével vagy ún. "curry" függvényekkel (H. B. Curry után). Nézzünk egy olyan függvényt, amely összead két egész számot. Ez rendezett n -esekkel megvalósítva:
Ennek a függvénynek a bemenete egy int * int rendezett pár. A Curry féle verziója ennek a függvénynek zárójelek vagy vesszők nélkül van definiálva:
Ennek a függvénynek a típusa int -> (int -> int). Tehát ez egy olyan függvény, amely egy egész számból egy olyan függvényt csinál amely egészekből egészeket csinál. A függvény argumentumait zárójelek nélkül adhatjuk meg:
Csak egy argumentumot megadva az eredmény a függvény "parciális kiértékelése lesz". Például meghívva az "add" függvényt csak a "2" paraméterrel az eredmény egy olyan függvény lesz, amely kettőt ad a bemenetéhez.
A Curry függvények hasznosak lehetnek olyan esetekben, amikor függvényeket adunk át egy másik függvény paraméterének.
Erre egy egyszerű példát mutatunk. Adott egy f függvény, a twice f-et alkalmazza paraméterként.
Az egész szám következő száma függvény pedig:
Ez haszhálható a twice paramétereként.
A twice egy egyszerű függvény (curry függvény speciális esete), melynek paramétere saját maga. Most definiáljuk az általános iterációs függvényt. Ez a curry függvény egy curry függvényt ad eredményként.
Legegyszerűbb esetben f0 = id, az identitás függvény. Ha n pozitív
Most implemetáljuk az iter függvényt Standard ML-ben.
Megvizsgálunk két magasabb rendű Standard ML függvényt, melyek közül az egyik egy függvényt transzformál az ő curry alakjába, a másik egy curry függvényt tuple-alakba.
Ha x és y értékek, f és g függvények, akkor mindig létezik:
A függvényeket név nélkül is definiálhatjuk, a következő szintaxissal:
fn < parameters > => < expression >
Példa:
Ez nagyon hasznos tud lenni, ha magasabbrendű függvényeket használunk, mint a map:
Az ML -ben megtalálhatóak a szokásos matematikai és stringkezelő függvények, például:
+ | egész vagy valós összeadás | |
- | egész vagy valós kivonás | |
* | egész vagy valós szorzás | |
/ | valós osztás | |
div | egész osztás | pl. 27 div 10 is 2 |
mod | maradék | pl. 27 mod 10 is 7 |
^ | string konkatenáció | pl. "cub"^"a" |
Ezek mind infix operátorok, tehát két argumentum között jelennek meg.
Áttekintésképpen most az ML előre definiált függvényei következnek:
Mindenképpen meg kell hívni:
Referenciák jelentősége miatt egy kicsit részletezem
Létezik referencia minta, lekérdezhető műveletekben kényelmesen helyettesíti a !-t:
A while felt do kif kifejezés a hagyományos ciklust írhatjuk le:
Rejtett állapot:
Belső állapottal rendelkező objektum létrehozására mutat példát ez a fv:
Az objektum így használható:
Fontos, hogy minden példánynak saját állapota van, nem pedig közös az összesnek!
fold, revfold.
app,revapp.