U L i k o o L matemaatika-informaatikateaduskond



Yüklə 0,53 Mb.

səhifə17/23
tarix13.11.2017
ölçüsü0,53 Mb.
1   ...   13   14   15   16   17   18   19   20   ...   23

do in e

≡ e


do e

1

; st in e



≡ let _e = e

1

in



(\ Unit : Unit . do st in e) _e

do . p = e

1

; st in e ≡ let _e = e



1

in

(\ p : typeof _e . do st in e) _e



do . p <- e

1

; st in e ≡ let _e = e



1

in

(\ p : basetypeof _e . do st in e) _e



do st end

≡ do st in Unit

Siin st t¨ahendab suvalist (t¨uhja v˜oi mittet¨uhja) do-notatsiooni lausete jada.

Operaator basetypeof sarnaneb operaatoriga typeof, kuid avaldise t¨u¨ubist

eemaldatakse k˜oik tipmisel tasemel olevad monaadid. Seega kui avaldis on

monaadilist t¨u¨upi (t¨apselt ¨uhe monaadiga), siis kasutatakse funktsiooni ra-

kendamise operaatori $ asemel operaatorit =<<.

N¨aeme, et erinevalt Haskellist on do-avaldisel kaks erinevat kuju —

do st in e ja do st end. Esimese variandi korral tagastatakse do-avaldise

tulemusena avaldise e v¨a¨artus. Siin on tagastatav v¨a¨artus ¨ulej¨a¨anud lause-

test eraldatud (ning ¨ulelaadimise t˜ottu ei ole seal return vaja kasutada),

erinevalt Haskellist, kus tagastatav v¨a¨artus m¨a¨aratakse do-konstruktsiooni

viimase lausega, mille ette tuleb enamasti return kirjutada. Teise varian-

di korral on do-avaldise tulemuseks ¨uhikt¨u¨ubi v¨a¨artus, mitte viimase lause

v¨a¨artus. Seega Fumontrixis on tagastusv¨a¨artus selgelt ¨ulej¨a¨anud lausetest

eraldatud, mis muudab koodi lugemise lihtsamaks.

Erinevalt Haskellist ei ole Fumontrixis monaadidel funktsiooni fail. Kui

do-avaldises n¨aidisesobitamine eba˜onnestub, siis on tulemuseks ⊥. Samas ei

ole see automaatne funktsiooni fail v¨aljakutsumine h¨adavajalik, kuna selle

sobitumise kontrolli ja eba˜onnestumise korral mingi funktsiooni v¨aljakutsu-

mise saab ka k¨asitsi teha, nagu j¨argnevas n¨aites (vt ka [1], jaotis 3.14):

do

st1;



. e <- f 10;

in

case e of



Just x -> do st2 in expr;

_

-> fail;



end;

See vastaks siis j¨argnevale koodile, kui automaatne fail v¨aljakutsumine oleks

olemas:

do

st1;



55


. Just x <- f 10;

st2;


in

expr


6.5.3

Mitme monaadi korraga kasutamine

Seni vaatlesime p˜ohiliselt juhtu, kus korraga on kasutusel maksimaalselt ¨uks

monaad. M˜onikord on vaja korraga mitut monaadi kasutada. Olgu

f : M

1

(M



2

a -> M


3

b) ja


x : M

4

(M



2

a)

Siis peaks funktsiooni rakendamisel olema



f x : M

1

(M



4

(M

3



b)) Siin M

1

, M



2

, M


3

ja M


4

on 0 v˜oi enama monaadi

kompositsioonid (need kompositsioonid ei pruugi ise olla monaadid).

Fumontrixis ongi v˜oimalik selliselt kasutada korraga mitut monaadi. Iga

funktsiooni rakendamise korral koostatakse kasutatavate monaadide monaa-

difunktsioonide p˜ohjal sobiv funktsiooni rakendamise operaator ja rakenda-

takse seda. Siin on erinevaid funktsiooni rakendamise operaatoreid palju roh-

kem kui 10, mis oli ¨uhe monaadi korral, aga programmeerija ei pea nende

p¨arast muretsema, kuna tavaline funktsiooni rakendamise operaator t¨o¨otab

k˜oigil neil juhtudel.

Kui M

1

= M



4

= M


3

= M ehk kasutusel on ainult ¨uks monaad, siis oleks

f x : M (M (M b)). Eelnevalt vaadeldud ¨uhe monaadiga juhu korral oli tu-

lemuseks f x : M b. Fumontrixis koondatakse sellisel juhul (monaadifunkt-

siooni join abil) k˜orvutisattuvad v˜ordsed monaadikonstruktorid. Esialgsete

kompositsioonide M

1

, M


4

, M


3

seest k˜orvuti olnud v˜ordseid monaadikonst-

ruktoreid ei koondata.

Kui funktsiooni rakendamise operaator on selliselt erinevate monaadide

kasutamiseks ¨ule laetud, siis saab do-avaldises vabalt kasutada vaheldumisi

erinevaid monaade. Sellisel juhul v˜oib l˜opuks do-avaldise t¨u¨up olla midagi

sellist:

M1 (M2 (M3 (M1 (M2 (M3 Int))))).

Siin M1, M2, M3 on ¨uksikud monaadid, mitte kompositsioonid.

Sellist t¨u¨upi v¨a¨artusest t¨aisarvu k¨attesaamiseks v˜oiks kirjutada run funkt-

siooni, mis t¨o¨otab k˜oigi v¨a¨artuste jaoks, mille t¨u¨up on kujul

m

1



(m

2

... (m



n

a)...),


ning annab v¨alja t¨u¨upi M a v¨a¨artuse, kus M on mingi monaad. Siin monaadid

m

1



, m

2

, ..., m



n

on mingi t¨u¨ubiklassi esindajad.

Selle jaoks on vaja, et iga monaadi m

i

jaoks oleks olemas teisendaja t¨u¨upi



m

i

a -> M a. Muidugi oleks v˜oimalik see teisendaja igal monaadi kasuta-



misel ilmutatult v¨alja kutsuda, kuid see l¨aheks kohmakaks. Mugavam oleks

56



v¨alja kutsuda run funktsioon ¨uhe korra terve do-avaldise jaoks.

GHC-s saab teha midagi sellist:

class ListRunnable a b | a -> b where

runList :: a -> [b]

newtype Stop a = Stop a

maybeToList :: Maybe a -> [a]

maybeToList (Just x) = [x]

maybeToList Nothing = []

instance ListRunnable (Stop a) a where

runList (Stop x) = [x]

instance ListRunnable a b => ListRunnable [a] b where

runList xs = concat (map runList xs)

instance ListRunnable a b => ListRunnable (Maybe a) b where

runList xs = concat (map runList (maybeToList xs))

(>=>) :: forall a1 r (m :: * -> *).

(Monad m) => m a1 -> (a1 -> r) -> m r

(>=>) = flip liftM

lr =


[1,2,3] >=> \ x ->

Just 700 >=> \ y ->

[10,20] >=> \ z ->

Stop (x + y + z)

Siin kasutame korraga kahte monaadi: [] ja Maybe. lr on t¨u¨upi

forall t. (Num t) => [Maybe [Stop t]]

ehk

[Maybe [Stop Integer]]



kui arvut¨u¨ubid monomorfsed oleks. Siis

runList lr :: [Integer]

Kuna GHC ei luba t¨u¨ubitaseme funktsioonides tulemuse t¨u¨ubi defineerimisel

vaikevariante kasutada (vt jaotist 5.3.5), siis on siin vaja konstruktor Stop

sisse tuua.

Fumontrixis saame sama n¨aite realiseerida t¨u¨ubitaseme funktsioonidega:

57





Dostları ilə paylaş:
1   ...   13   14   15   16   17   18   19   20   ...   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ə