U L i k o o L matemaatika-informaatikateaduskond



Yüklə 0,53 Mb.

səhifə9/23
tarix13.11.2017
ölçüsü0,53 Mb.
1   ...   5   6   7   8   9   10   11   12   ...   23

Siis saab kasutada avaldisi nagu type f (value 2) ja type f (value True).

See s¨untaks on natuke kohmakas, kuna t¨u¨ubitaseme ja andmetaseme vahel

liikumiseks tuleb kasutada v˜otmes˜onu type ja value. Soovi korral v˜oib lisada

s¨untaktilist suhkrut, mis teeb selle tasemete vahel liikumise mugavamaks, siis

v˜oiks n¨aiteks kirjutada eelnevalt vaadeldud avaldised kujul ’f 2 ja ’f True

ning t¨u¨ubitaseme funktsiooni definitsioonis type x asemel @x. Praegu ei ole

lihtsuse huvides seda keelde lisatud.

Liiki @ -> @ t¨u¨ubitaseme funktsioonid ehk need, mis seavad v¨a¨artusele

vastavusse v¨a¨artuse, sarnanevad v¨a¨artustaseme funktsioonidega. K˜oiki v¨a¨ar-

tustaseme funktsioone saab ka t¨u¨ubitaseme funktsioonidena defineerida. Sa-

mas v¨a¨artustasemel saab defineerida ainult neid funktsioone, millel on t¨u¨u-

bis¨usteemis olemas t¨u¨up.

T¨u¨ubitasemel on v˜oimalik defineerida ka selliseid funktsioone, millel t¨u¨u-

bis¨usteemis t¨u¨upi ei ole (selline on ka funktsioon f viimases n¨aites). See ei

t¨ahenda staatilise t¨u¨ubikontrolli puudumist. Sellisel funktsioonil on olemas

implitsiitne t¨u¨up. Iga t¨u¨ubi jaoks saab staatiliselt kontrollida, kas see t¨u¨up

sobib antud funktsiooni argumendiks ja, kui sobib, siis saab staatiliselt m¨a¨a-

rata rakendamise tulemuse t¨u¨ubi.

Kuna t¨u¨ubitaseme funktsioonil t¨u¨ubis¨usteemis t¨u¨upi ei ole, siis ei saa seda

anda argumendiks andmetaseme funktsioonile. K¨ull aga saab seda anda ar-

gumendiks teisele t¨u¨ubitaseme funktsioonile (n¨aiteks liiki (@ -> @) -> @).

Samuti saab (n¨aiteks liiki @ -> @ -> @) t¨u¨ubitaseme funktsiooni tulemu-

seks olla teine t¨u¨ubitaseme funktsioon, seega saab kasutada curried-kujul

t¨u¨ubitaseme funktsioone. Seega t¨u¨ubitaseme funktsioonid on t¨u¨ubitasemel

first-class.

5.2.2


ubitaseme funktsioonid ja t¨



ubiinferents

Kuna t¨u¨ubitaseme funktsiooni korral ei ole vaja m¨a¨arata argumendi t¨u¨upi

(liik tuleb siiski m¨a¨arata), siis saab t¨u¨ubitaseme funktsioone kasutada t¨u¨u-

biinferentsi asemel. N¨aiteks v˜oime andmetaseme funktsiooni

double = \ x : Int . x + x;

asemel defineerida t¨u¨ubitaseme funktsiooni:

type double = \ x : @ . value (type x) + (type x);

Erinevalt andmetasemest ei ole t¨u¨ubitasemel funktsiooni argumendi t¨u¨upi

m¨a¨aratud. Samas selle funktsiooni rakendamisel mingit muud t¨u¨upi kui Int

argumendile tuleb staatiliselt t¨u¨ubiviga (kuna muud t¨u¨upi v¨a¨artust ei saa

funktsiooni + argumendiks anda).

30



Samas v˜oib juhtuda, et programmeerija kirjutab kogemata + asemel ||.

Esimeses definitsioonis tuleb see viga kohe v¨alja, kuna x t¨u¨ubiks on m¨a¨a-

ratud Int, kuid || ootab argumendiks Bool-t¨u¨upi v¨a¨artust. T¨u¨ubitaseme

funktsiooni korral ei tule see viga definitsiooni kontrollimisel v¨alja. Definit-

sioon

type double = \ x : @ . value (type x) || (type x);



on t¨aiesti t¨u¨ubikorrektne (ja rakendatav Bool-t¨u¨upi v¨a¨artustele), kuid see

erineb sellest, mida programmeerija plaanis kirjutada. Viga tuleb v¨alja alles

siis, kui funktsiooni ¨uritatakse rakendada Int-t¨u¨upi v¨a¨artusele, kuid n¨aiteks

teegi kirjutamisel v˜oib juhtuda, et m˜onda defineeritud funktsiooni ei raken-

data kordagi (selle teegi koodis).

Sama probleem esineb ka t¨u¨ubiinferentsi korral. Kui Haskellis kirjutada

definitsioon

double x = x || x

siis translaator ei tea, et programmeerija plaanis argumendi t¨u¨ubiks Int, ning

t¨u¨ubiviga j¨a¨ab avastamata.

See on ka ¨uks p˜ohjus, miks Fumontrixis t¨u¨ubiinferentsi ei kasutata. Vaja-

duse korral saab kasutada t¨u¨ubitaseme funktsioone, kuid siis peab program-

meerija lihtsalt ettevaatlikum olema. Haskellis kasutatakse t¨u¨ubiinferentsi

alati ja programmeerija ei saa seda keelata. GHC-s saab k¨ull funktsiooni ar-

gumendile t¨u¨ubiannotatsiooni lisada, kuid programmeerija v˜oib selle m˜ones

kohas ¨ara unustada. Translaator sellisel juhul ei hoiata ja t¨u¨ubivead v˜oivad

j¨a¨ada avastamata.

T¨u¨ubitaseme funktsioonide korral esineb veel ¨uks probleem. N¨aiteks de-

finitsioon

type tb = \ x : @ . value 3 + True;

t¨u¨ubiviga ei anna, kuigi selles sisalduv avaldis 3 + True ei ole t¨u¨ubikor-

rektne. Siin on lihtsalt tegemist t¨u¨ubitaseme funktsiooniga, mis ei ole ¨uhegi

argumendi korral defineeritud, samas kui funktsioon ise on defineeritud. Iga

katse seda funktsiooni rakendada annab t¨u¨ubivea. T¨u¨ubiviga on t¨u¨ubitaseme

analoog andmetaseme ⊥-le. Vaadeldaval juhul alamavaldis ei s˜oltu funktsioo-

ni argumendist x, kuid ¨uldjuhul v˜oib s˜oltuda ning sel juhul on juba keeruline

kindlaks teha, kas funktsioon annab iga argumendi korral t¨u¨ubivea. Fumon-

trixis sellist anal¨u¨usi ei ¨uritata teha. Selliste vigade v¨altimiseks v˜oib t¨u¨ubita-

seme funktsiooni argumendist mittes˜oltuvad alamavaldised t¨u¨ubilambda alt

v¨alja tuua eraldi definitsioonidesse. See muudab k¨ull koodi hakitumaks.

Liigivead ja tundmatute t¨u¨ubiidentifikaatorite kasutused tulevad siiski

kohe t¨u¨ubitaseme funktsiooni defineerimisel v¨alja, kuna need ei s˜oltu kunagi

argumendist (argumendi liik on fikseeritud).

31



5.3



ubitaseme funktsioonid Haskellis

5.3.1


Ad-hoc-pol¨

umorfsed funktsioonid

Haskell 98-s on olemas t¨u¨ubis¨unon¨u¨umid, mille abil on v˜oimalik defineerida

ainult parameetriliselt pol¨umorfseid t¨u¨ubitaseme funktsioone. Samuti on v˜oi-

malik kasutada t¨u¨ubiklasse, mille abil saab defineerida pol¨umorfseid funkt-

sioone. GHC-s on selliselt defineeritavate pol¨umorfsete funktsioonide hulk

palju suurem kui Haskell 98-s. Kuna t¨u¨ubis¨unon¨u¨umid on Haskellis v¨aga pii-

ratud v˜oimalustega, siis neid me selles t¨o¨os l¨ahemalt ei vaatle ning Haskelli

v˜oi GHC t¨u¨ubitaseme funktsioonide [5] all peame silmas t¨u¨ubiklasside abil

defineeritavaid pol¨umorfseid funktsioone.

Haskell 98-s olemas ainult ¨uhe parameetriga t¨u¨ubiklassid, mille abil on

v˜oimalik defineerida ad-hoc-pol¨umorfseid funktsioone (erinevat t¨u¨upi argu-

mentide korral v˜oib tulemuse v¨a¨artuse leidmiseks argumendi v¨a¨artuse p˜oh-

jal kasutada erinevat koodi), mille tulemuse t¨u¨up s˜oltub argumendi t¨u¨ubist

ainult parameetriliselt pol¨umorfselt (tulemuse t¨u¨up tuleb avaldada ¨uhe t¨u¨u-

biavaldisena, mis v˜oib argumendi t¨u¨upi sisaldada ainult parameetrina ehk

t¨u¨ubimuutujana). N¨aiteks v˜oime kirjutada funktsiooni, mis nii t˜oev¨a¨artuste-

le kui t¨aisarvudele seab vastavusse t¨aisarvu, kuid erineva koodiga:

class C1 a where

f1 :: a -> Integer

instance C1 Bool where

f1 b = bool2int b

instance C1 Integer where

f1 x = x


Siis n¨aiteks f1 (3::Integer) annab tulemuseks 3 ja f1 True annab tule-

museks 1. Siin eeldame, et eelnevalt on olemas definitsioonid

int2bool x = x /= 0

bool2int b = if b then 1 else 0

Samuti v˜oime Haskell 98-s kirjutada funktsiooni, mis t˜oev¨a¨artustele seab

vastavusse t˜oev¨a¨artuste listi ning t¨aisarvudele t¨aisarvude listi, kuid erineva

koodiga:

class C2 a where

f2 :: a -> [a]

instance C2 Bool where

f2 b = [b,b]

instance C2 Integer where

f2 x = [x,x,x]

32





Dostları ilə paylaş:
1   ...   5   6   7   8   9   10   11   12   ...   23


Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2019
rəhbərliyinə müraciət

    Ana səhifə