Učinki#

Učinki v OCamlu#

Za začetek si poglejmo nekaj primerov učinkov v OCamlu. Prva (in zelo pogosto uporabljana) je print_endline, ki sprejme niz ter ga izpiše na zaslon in vrne prazen nabor. V splošnem nam prisotnost tipa unit v OCamlu sporoča, da se bodo sprožili stranski učinki, saj sicer funkcija, ki bi vrnila unit, ne bi storila ničesar koristnega.

print_endline
- : string -> unit = <fun>
print_endline "Hello, world!"
Hello, world!
- : unit = ()

Pri klicu funkcij z učinki je včasih uporabna tudi funkcija List.iter, ki dano funkcijo pokliče na vseh elementih seznama. Podobna je funkciji List.map, le da seznam vrnjenih praznih naborov zavrže, saj ga redkokdaj uporabljamo.

List.map print_endline ["am"; "bam"; "pet"; "podgan"]
am
bam
pet
podgan
- : unit list = [(); (); (); ()]
List.iter print_endline ["am"; "bam"; "pet"; "podgan"]
am
bam
pet
podgan
- : unit = ()

Za delo z psevdonaključnimi vrednostmi je na voljo knjižnica Random. Pogosto uporabljani funkciji tam sta Random.bool, ki ob vsakem klicu vrne naključno logično vrednost, in Random.int, ki za neko število \(m\) vrne naključno celo število med 0 in \(m - 1\). Pri uporabi psevdonaključnih števil moramo paziti, da na začetku nastavimo ustrezno seme, saj sicer OCaml vedno začne z enakim. Na primer, spodnji klic bo ob prvem klicu vedno vrnil število 9344.

Random.int 100000
- : int = 9344

Seme lahko najbolj enostavno nastavimo z Random.self_init, ki ga nastavi glede na trenuten čas, stanje procesov, …, skratka dovolj naključno.

Random.self_init ()
- : unit = ()
Random.int 100000 (* tu je nemogoče napovedati, kaj bo klic vrnil *)
- : int = 69580

Za branje s konzole uporabimo funkcijo read_line.

read_line
- : unit -> string = <fun>

Tudi tu nam prisotnost tipa unit nakazuje, da se bodo najverjetneje zgodili učinki, saj bi funkcija samo iz praznega nabora težko izračunala kakšno zanimivo vrednost. Žal v učbeniku te funkcije ne moremo smiselno poklicati.

raise
- : exn -> 'a = <fun>