Vaje#
Naloga 1#
Napišite prestreznik
mute, ki prestreže vgrajeniPrintin prepreči izpis. Program naj nadaljuje nemoteno.Napišite prestreznik
shift_text_right n, ki vse izpisano besedilo zamakne v desno zanmest.Prestreznik
underlinevsako izpisano vrstico podčrta (tako da v novi vrstici izpiše primerno število znakov-).Prestreznik
custom_separator sepnaj poskrbi, da se ločeno izpisani tekst ne loči z\ntemveč separatorjemsep.Napišite prestreznik
counter limit, ki šteje izpise in vrne rezultat, samo, če je bilo izpisanih manj kotlimitznakov. Če je bilo izpisanih več, naj vrneNone.Popravite zgornje prestreznike, da bodo ponovno sprožili učinke
Print, ki ga bo ujel limitni prestreznik.
Naloga 2#
Napišite učinka
Get : unit -> intinPut : int -> unitin program, ki ju smiselno uporablja.Napišite prestreznik
state, ki program ustrezno implementira učinkaGetinPutv monadični obliki - izračun pretvori v funkcijo, ki sprejme začetno vrednost stanja in vrne rezultat.
Naloga 3#
Vzemi drevo, ki ga definira naslednji tip:
type 'a tree
= Empty
| Node of tree * 'a * tree
type direction = Left | Right
in učinek Pick : unit -> direction.
Napišite funkcijo
explore : int tree -> int, ki raziskuje drevo in podatke združuje s pomočjo globalne funkcijeop : 'a -> int -> 'a. Raziskovanje praznega drevesa naj vrne0, raziskovanje nepraznega pa naj najprej izvede učinekPickin glede na rezultat izbere levo ali desno poddrevo, nadaljuje raziskovanje tega poddrevesa in vrne rezultat združen z vrednostjo v korenu.Napišite prestreznike in pripadajočo funkcijo
op, ki glede na funkcijoexplorevrnejo naslednje rezultate:Vrednost minimalne poti v drevesu
Vrednost maksimalne poti v drevesu
Število vseh poti v drevesu
Vrednosti vseh poti v drevesu
Povprečno vrednost poti v drevesu
Naloga 4#
Želimo narediti prestreznik za memoizacijo. Že izračunane vrednosti bomo (neučinkovito) hranili v seznamu parov.
Napišite funkciji za delo s seznami parov
find : 'a -> ('a * 'b) list -> 'b optioninsave : 'a -> 'b -> ('a * 'b) list -> ('a * 'b) list.Da si poenostavimo življenje, se osredotočimo zgolj na funkcije
int -> int. V nadaljevanju uporabljamo preimenovanjitype arg = intintype result = int. Naša memoizacija bo potrebovala pomnilnik, zato bomo zanj definirali poseben prestreznik. Definirajte učinkaLookup : arg -> result optioninRemember : arg * result -> unit. Nato zanju napišite prestreznikmemory, ki upravlja s pomnilnikom tipa(arg * result) list.Sedaj lahko funkcije že uporabljajo pomnilnik za memoizacijo, vendar bi želeli, da je memoizacija funkcije zgolj eno od možnih izvajanj. Zato definirajte učinek
Evaluate : ((int -> int) * int) -> int, ki sprejme funkcijo in argument, ter nam vrne rezultat. Funkcij sedaj ne kličemo več kotf xtemveč kotperform (Evaluate (f, x))(priporočam, da si ustvarite pomožno funkcijoeval f x = ...za lepšo sintakso). Napišite prestreznikno_memo, ki funkcijo izvede, kot bi se izvedla sicer. Nato napišite še prestreznikmemo, ki funkcijo memoizira.
Namig: Če želite rekurzivne prestreznike, jih definirajte kot let rec h () = handler ... kjer jih lahko sedaj v telesu definicije uporabite z with h () handle ....
Naloga 5#
Generatorji so funkcije, ki zaporedoma uporabljajo učinek Yield : int -> unit.
Napišite funkcijo, ki generira vsa naravna števila.
Napišite funkcijo
collect n gen, ki iz generatorjagenpobere prvihnvrednosti.Napišite prestreznik
generator gen, ki na zahtevoGenerate : unit -> intgenerira novo vrednost iz generatorjagen.
Namig: Eden od možnih načinov je, da z dodatnim prestreznikom generatorje iz tipa unit -> unit!{Yield} pretvorite v tip unit -> gen. Tu je gen novo definiran tip, ki označuje, da je generator bodisi končal, bodisi pa je proizvedel element in svoje posodobljeno stanje (ponovno tipa unit -> gen). Če potrebujete, ima Eff vgrajeno funkcijo failwith msg.