Rekurzija#

Pri konstruktih OCamla, ki smo jih spoznali do sedaj, morda presenetljivo ni bilo nobene omembe zank, ki so eno osnovnih orodij v Pythonu. V resnici OCaml podpira tudi zanke, vendar jih bomo spoznali kasneje. Namesto tega večino časa uporabljamo vgrajene funkcije kot na primer List.map ali List.fold_left, ki jo bomo še spoznali. Če pa ustrezne funkcije ni, jo napišemo sami s pomočjo rekurzije.

Če želimo definirati rekurzivno funkcijo, jo moramo podati z let rec:

let rec vsota_prvih n =
  if n = 0 then 0 else vsota_prvih (n - 1) + n
val vsota_prvih : int -> int = <fun>
vsota_prvih 100
- : int = 5050

Seveda ne gre brez klasičnih primerov rekurzivnih funkcij: fakultete in Fibonaccijevih števil.

let rec fakulteta n =
  if n = 0 then 1 else n * fakulteta (n - 1)
val fakulteta : int -> int = <fun>
fakulteta 10
- : int = 3628800
let rec fib n =
  if n = 0 then 0
  else if n = 1 then 1
  else fib (n - 1) + fib (n - 2)
val fib : int -> int = <fun>

Zgornja definicija je precej neučinkovita, zato si lahko pomagamo s pomožno funkcijo, ki deluje veliko hitreje.

let hitri_fib n =
  let rec aux n a b =
    if n = 0 then a else aux (n - 1) b (a + b)
  in aux n 0 1
val hitri_fib : int -> int = <fun>

Z uporabo and lahko hkrati definiramo tudi več rekurzivnih funkcij:

let rec je_sodo n =
  n = 0 || je_liho (n - 1)

and je_liho n =
  n <> 0 || je_sodo (n - 1)
val je_sodo : int -> bool = <fun>
val je_liho : int -> bool = <fun>

O učinkovitosti tega primera raje ne izgubljajmo besed.

Ujemanje vzorcev#

Poleg neučinkovitosti pa je imela funkcija fib še eno težavo: gnezdene pogojne stavke. Namesto njih v funkcijskem programiranju uporabljamo učinkovitejši in preglednejši pristop ujemanja vzorcev, kjer za vsako izmed možnih oblik vrednosti podamo ustrezno nadaljevanje programa.

Konstrukt match#

Med večimi vzorci se v OCamlu odločimo s pomočjo konstrukta match, ki sprejme več vej, ločenih z |, nato pa vrne prvo, ki ustreza danemu vzorcu. Na primer, zgornje funkcije bi lahko pisali kot:

let rec vsota_prvih n =
  match n with
  | 0 -> 0
  | _ -> vsota_prvih (n - 1) + n

let rec fakulteta n =
  match n with
  | 0 -> 1
  | _ -> n * fakulteta (n - 1)

let rec fib n =
  match n with
  | 0 -> 0
  | 1 -> 1
  | _ -> fib (n - 1) + fib (n - 2)
val vsota_prvih : int -> int = <fun>
val fakulteta : int -> int = <fun>
val fib : int -> int = <fun>

Če je n enak 0 oz. v zadnjem primeru 1, vrnemo ustrezno robno vrednost, če pa je n karkoli drugega, kar označimo s slepim vzorcem (ang. wildcard) _, pa rekurzivno izračunamo splošni primer.

Konstrukt function#

Pogosto bomo uporabili ujemanje vzorcev na zadnjem argumentu funkcije. Za ta primer lahko uporabimo tudi zapis z function:

let rec vsota_prvih =
  function
  | 0 -> 0
  | n -> vsota_prvih (n - 1) + n

let rec fakulteta =
  function
  | 0 -> 1
  | n -> n * fakulteta (n - 1)

let rec fib =
  function
  | 0 -> 0
  | 1 -> 1
  | n -> fib (n - 1) + fib (n - 2)
val vsota_prvih : int -> int = <fun>
val fakulteta : int -> int = <fun>
val fib : int -> int = <fun>

V tem primeru za splošni primer nismo uporabili slepega vzorca _, saj smo na desni strani potrebovali vrednost. Namesto tega smo uporabili spremenljivko, ki tako kot _ ustreza poljubnim vrednostim, le da jih še poimenuje, da jih lahko uporabimo v nadaljevanju.

Pokritost vzorcev#

Vzorci se izvajajo od prvega do zadnjega, zato moramo biti pozorni na njihov vrstni red. Recimo, da imamo funkcijo, ki iz končnice datoteke napove ime programskega jezika:

let ime_jezika =
  function
  | ".ml" -> "OCaml"
  | ".py" -> "Python"
  | ".rs" -> "Rust"
  | _ -> "???"
val ime_jezika : string -> string = <fun>
ime_jezika ".java"
- : string = "???"

Poskusimo funkcijo napisati kot:

let ime_jezika =
  function
  | ".ml" -> "OCaml"
  | ".py" -> "Python"
  | _ -> "???"
  | ".rs" -> "Rust"
File "[12]", line 6, characters 4-9:
6 |   | ".rs" -> "Rust"
        ^^^^^
Warning 11 [redundant-case]: this match case is unused.
val ime_jezika : string -> string = <fun>

OCaml nas je opozoril, da zadnja veja nikoli ne bo uporabljena, saj bo tretji vzorec ustrezal vsem primerom.

ime_jezika ".rs"
- : string = "???"

Prav tako nas OCaml opozori, če na kakšen primer pozabimo, saj bo ob izvajanju sicer lahko prišlo do napake:

let ime_jezika =
  function
  | ".ml" -> "OCaml"
  | ".py" -> "Python"
  | ".rs" -> "Rust"
File "[14]", lines 2-5, characters 2-19:
2 | ..function
3 |   | ".ml" -> "OCaml"
4 |   | ".py" -> "Python"
5 |   | ".rs" -> "Rust"
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
""
val ime_jezika : string -> string = <fun>
ime_jezika ".java"
Exception: Match_failure ("[14]", 2, 2).
Raised at ime_jezika in file "[14]", line 2, characters 2-73
Called from Stdlib__Fun.protect in file "fun.ml", line 33, characters 8-15
Re-raised at Stdlib__Fun.protect in file "fun.ml", line 38, characters 6-52
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-150

Možni vzorci#

Osnovni vzorci#

Videli smo že, da lahko za vzorce uporabimo poljubne konstante, slepi vzorec _ ali spremenljivke.

let ali_je_res =
  function
  | true -> "res je"
  | false -> "ni res"
val ali_je_res : bool -> string = <fun>
let ime_stevila =
  function
  | 1 -> "ena"
  | 2 -> "dva"
  | _ -> "veliko"
val ime_stevila : int -> string = <fun>
let ime_stevila =
  function
  | 1 -> "ena"
  | 2 -> "dva"
  | x -> "število " ^ string_of_int x
val ime_stevila : int -> string = <fun>

Združeni vzorci#

Več zaporednih vzorcev, ki imajo enako vejo, lahko združimo v enega:

let je_prestopno leto =
  (leto mod 4 = 0 && leto mod 100 <> 0) || leto mod 400 = 0
  
let dolzina_meseca leto =
  function
  | 4 | 6 | 9 | 11 -> 30
  | 2 -> if je_prestopno leto then 29 else 28
  | _ -> 31
val je_prestopno : int -> bool = <fun>
val dolzina_meseca : int -> int -> int = <fun>

Vzorci za nabore#

Tako kot lahko vrednosti z nabori sestavljamo v gnezdene vrednosti, lahko gnezdimo tudi vzorce. Nabore primerjamo z vzorci oblike (p₁, p₂, ...), pri čemer so p₁, p₂ spet lahko poljubni nadaljnji vzorci.

let polozaj_tocke =
  function
  | (0, 0) -> "izhodišče"
  | (_, 0) -> "abscisa"
  | (0, _) -> "ordinata"
  | (_, _) -> "nekje drugje"
val polozaj_tocke : int * int -> string = <fun>

Spomnimo se, da vzorec s spremenljivko ustreza poljubni vrednosti. Kaj bi se zgodilo, če bi vzorec (x, x) primerjali z vrednostjo (4, 2)? Število 4 ustreza prvemu vzorcu x, ravno tako pa število 2 ustreza drugemu vzorcu x. Toda na katero vrednost naj se veže x? Da se izognemo dvoumnosti, nam OCaml vsako spremenljivko v vzorcu dovoli napisati samo enkrat. Tako ne moremo napisati:

let polozaj_tocke =
  function
  | (0, 0) -> "izhodišče"
  | (_, 0) -> "abscisa"
  | (0, _) -> "ordinata"
  | (x, x) -> "diagonala"
  | (_, _) -> "nekje drugje"
File "[21]", line 6, characters 8-9:
6 |   | (x, x) -> "diagonala"
            ^
Error: Variable x is bound several times in this matching

Lahko pa napišemo:

let polozaj_tocke =
  function
  | (0, 0) -> "izhodišče"
  | (_, 0) -> "abscisa"
  | (0, _) -> "ordinata"
  | (x, y) -> if x = y then "diagonala" else "nekje drugje"
val polozaj_tocke : int * int -> string = <fun>

Varovani vzorci#

Vsak vzorec lahko z uporabo when zavarujemo z logičnim pogojem. Takemu vzorcu ustrezajo samo tiste vrednosti, za katere je logični pogoj resničen. Zgornji primer bi tako lepše napisali kot:

let polozaj_tocke =
  function
  | (0, 0) -> "izhodišče"
  | (_, 0) -> "abscisa"
  | (0, _) -> "ordinata"
  | (x, y) when x = y -> "diagonala"
  | (_, _) -> "nekje drugje"
val polozaj_tocke : int * int -> string = <fun>

Razlika med varovanimi vzorci in običajnimi pogojnimi izrazi je v tem, da pri prvih v primeru neuspeha nadaljujemo z naslednjim vzorcem, pri drugih pa smo se že odločili za vejo. Na primer, z varovanimi vzorci lahko napišemo funkcijo, ki določi obliko trikotnika:

let veljaven_trikotnik a b c =
  a + b <= c || a + c <= b || b + c <= a

let oblika_trikotnika =
  function
  | (a, b, c) when not (veljaven_trikotnik a b c) -> "neveljaven"
  | (0, _, _) | (_, 0, _) | (_, _, 0) -> "izrojen"
  | (a, b, c) when a = b && b = c -> "enakostraničen"
  | (a, b, c) when a = b || b = c || a = c -> "enakokrak"
  | (_, _, _) -> "poljuben"
val veljaven_trikotnik : int -> int -> int -> bool = <fun>
val oblika_trikotnika : int * int * int -> string = <fun>

Če bi poskusili isto napisati brez varovanih vzorcev, a obdržati vzorce za izrojene primere, bi morali ujemanje pisati kot:

let oblika_trikotnika =
  function
  | (a, b, c) ->
      if not (veljaven_trikotnik a b c) then
        "neveljaven"
      else match (a, b, c) with
      | (0, _, _) | (_, 0, _) | (_, _, 0) -> "izrojen"
      | (a, b, c) ->
          if a = b && b = c then "enakostraničen"
          else if a = b || b = c || a = c then "enakokrak"
          else "poljuben"
val oblika_trikotnika : int * int * int -> string = <fun>

Vzorci za morebitne vrednosti#

Videli smo, da funkcija int_of_string sproži napako, če naleti na niz, ki ne predstavlja števila.

let opisuje_pozitivno_stevilo niz =
  int_of_string niz > 0
val opisuje_pozitivno_stevilo : string -> bool = <fun>
opisuje_pozitivno_stevilo "100"
- : bool = true
opisuje_pozitivno_stevilo "-100"
- : bool = false
opisuje_pozitivno_stevilo "sto"
Exception: Failure "int_of_string".
Raised by primitive operation at opisuje_pozitivno_stevilo in file "[26]", line 2, characters 2-19
Called from Stdlib__Fun.protect in file "fun.ml", line 33, characters 8-15
Re-raised at Stdlib__Fun.protect in file "fun.ml", line 38, characters 6-52
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-150

Vemo že, da je varnejša alternativa uporaba funkcije int_of_string_opt, ki vrača rezultate tipa int option.

int_of_string_opt "100"
- : int option = Some 100
int_of_string_opt "-100"
- : int option = Some (-100)
int_of_string_opt "sto"
- : int option = None

Vendar imamo težavo, da se pri nadaljnji obdelavi tipi ne ujemajo:

let opisuje_pozitivno_stevilo niz =
  int_of_string_opt niz > 0
File "[33]", line 2, characters 26-27:
2 |   int_of_string_opt niz > 0
                              ^
Error: This expression has type int but an expression was expected of type
         int option

To je sicer nerodno, ampak v resnici dobro, saj nas tipi prisilijo, da obravnavamo vse robne primere. To lahko storimo z vzorcema None in Some p za morebitne vrednosti. Pri tem je p zopet lahko poljuben vzorec, ki se bo primerjal s prisotno vrednostjo.

V našem primeru nekaj, kar ne opisuje števila, tudi negativnega števila ne opisuje:

let opisuje_pozitivno_stevilo niz =
  match int_of_string_opt niz with
  | Some stevilo -> stevilo > 0
  | None -> false
val opisuje_pozitivno_stevilo : string -> bool = <fun>

Razstavljanje seznamov#

Vzorci za sezname fiksne dolžine#

Sezname fiksne dolžine primerjamo z vzorci oblike [p₁; p₂; …], pri čemer so p₁, p₂, … poljubni nadaljnji vzorci.

let citiraj_knjigo avtorji naslov =
  match avtorji with
  | [] -> naslov
  | [avtor] -> avtor ^ ": " ^ naslov
  | [prvi; drugi] -> prvi ^ ", " ^ drugi ^ ": " ^ naslov
  (* uporaba List.hd je slaba praksa *)
  | _ -> List.hd avtorji ^ " in ostali: " ^ naslov
val citiraj_knjigo : string list -> string -> string = <fun>
citiraj_knjigo [] "Telefonski imenik"
- : string = "Telefonski imenik"
citiraj_knjigo ["Tolkien"] "Gospodar prstanov"
- : string = "Tolkien: Gospodar prstanov"
citiraj_knjigo ["Pratchett"; "Gaiman"] "Dobra znamenja"
- : string = "Pratchett, Gaiman: Dobra znamenja"
citiraj_knjigo ["Golob"; "Kos"; "Vrabec"] "Ptiči Slovenije"
- : string = "Golob in ostali: Ptiči Slovenije"

Zadnja vrstica ni najboljša, saj funkcija lahko List.hd sproži napako, če je seznam prazen. Seveda vemo, da se to ne bo zgodilo, saj smo ta primer obravanavali že prej, a vseeno gre pri List.hd za slabo prakso. Bolje je uporabiti splošne vzorce za razstavljanje seznamov, ki si jih bomo ogledali podrobneje.

Verižni seznami#

Za razliko od drugih jezikov, v katerem si sezname lahko predstavljamo kot zaporedne podatke v pomnilniku, so seznami v OCamlu predstavljeni z verižnimi seznami. To pomeni, da ima vsak neprazen seznam glavo (prvi element) in rep (preostanek seznama, ki je zopet seznam). To nam omogoča, da sezname razstavimo na glavo in rep, kar je zelo uporabno pri rekurzivnih funkcijah.

Seznam z glavo h in repom t zapišemo kot h :: t. Tako je seznam [1; 2; 3; 4] samo krajši zapis za:

  [1; 2; 3; 4]
= 1 :: [2; 3; 4]
= 1 :: 2 :: [3; 4]
= 1 :: 2 :: 3 :: [4]
= 1 :: 2 :: 3 :: 4 :: []
"a" :: "b" :: ["c"; "d"]
- : string list = ["a"; "b"; "c"; "d"]

Poleg ::, ki glavo sestavi z repom, obstaja tudi @, ki stakne dva seznama.

["a"; "b"] @ ["c"; "d"]
- : string list = ["a"; "b"; "c"; "d"]

Za vajo lahko preverite, kateri izmed spodnjih seznamov so veljavni:

[1; 2] :: [3; 4] NE, ker `::` doda glavo, bi moralo biti na levi strani število, ali pa na desni strani seznam seznamov števil.
1 :: 2 :: 3 :: [] DA, to je seznam `[1; 2; 3]`.
[1; 2] @ [3; 4] DA, to je seznam `[1; 2; 3; 4]`.
1 @ 2 @ [3] NE, z `@` lahko stikamo samo sezname, `1` pa je število.
[1, 2] @ [3] NE, ker smo uporabili vejico namesto podpičja, zato je na levi seznam `[(1, 2)]`, na desni pa seznam števil.
1 :: 2 :: 3 NE, ker na koncu manjka rep.
[1; 2] @ [] DA, to je seznam `[1; 2]`.
[1; 2] :: [] DA, presenetljivo je tudi to veljaven seznam in sicer [[1; 2]].

Ko sestavljamo sezname, je videti, da imata :: in @ podobno vlogo, le da prvi na levi doda en element, drugi pa celoten seznam. Naj nas to ne zavede. Tako kot sta None in Some osnovna gradnika morebitnih vrednosti, sta [] in :: osnovna gradnika seznamov. Po drugi strani je @ pa je samo običajna rekurzivna funkcija.

Razstavljanje na glavo in rep#

To, da je :: osnovni gradnik seznamov, je še posebej očitno pri vzorcih, saj lahko prek vzorca p₁ :: p₂ sezname razstavljamo na glavo in rep. Tako bi lahko zgornjo funkcijo napisali kot:

let citiraj_knjigo avtorji naslov =
  match avtorji with
  | [] -> naslov
  | avtor :: [] -> avtor ^ ": " ^ naslov
  | prvi :: drugi :: [] -> prvi ^ ", " ^ drugi ^ ": " ^ naslov
  | prvi :: _ -> prvi ^ " in ostali: " ^ naslov
val citiraj_knjigo : string list -> string -> string = <fun>

Tako nam v zadnjem primeru ni treba uporabiti funkcije List.hd, da izluščimo glavo, saj smo to storili že z vzorcem.

citiraj_knjigo ["Pratchett"; "Gaiman"] "Dobra znamenja"
- : string = "Pratchett, Gaiman: Dobra znamenja"

Seveda lahko uporabimo tudi kombinacijo obeh vrst vzorcev za sezname:

let citiraj_knjigo avtorji naslov =
  match avtorji with
  | [] -> naslov
  | [avtor] -> avtor ^ ": " ^ naslov
  | [prvi; drugi] -> prvi ^ ", " ^ drugi ^ ": " ^ naslov
  | prvi :: _ -> prvi ^ " in ostali: " ^ naslov
val citiraj_knjigo : string list -> string -> string = <fun>

Enostavne rekurzivne funkcije#

S pomočjo razstavljanja seznamov na glavo in rep lahko napišemo vse rekurzivne funkcije na seznamih.

let rec vsota =
  function
  | [] -> 0
  | glava :: rep -> glava + vsota rep
val vsota : int list -> int = <fun>
vsota [1; 2; 3; 4]
- : int = 10

Pri dolžini ravnamo podobno, le da ignoriramo vrednost v glavi.

let rec dolzina =
  function
  | [] -> 0
  | glava :: rep -> dolzina rep + 1
val dolzina : 'a list -> int = <fun>
dolzina [1; 2; 3; 4]
- : int = 4

Tudi funkcija List.map je napisana na podoben način:

let rec map f =
  function
  | [] -> []
  | glava :: rep -> f glava :: map f rep
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
map String.length ["avto"; "pes"; "mačka"]
- : int list = [4; 3; 6]

Funkcija ( @ ) : 'a list -> 'a list -> 'a list, ki združi dva seznama v enega, pa je napisana kot:

let rec ( @ ) sez1 sez2 =
  match sez1 with
  | [] -> sez2
  | glava :: rep -> glava :: (rep @ sez2)
val ( @ ) : 'a list -> 'a list -> 'a list = <fun>
[1; 2; 3] @ [4; 5; 6]
- : int list = [1; 2; 3; 4; 5; 6]

Še enkrat lahko vidimo, da smo @ napisali kot običajno rekurzivno funkcijo, zato je v vzorcih ne moremo uporabiti.

Zlaganje seznamov#

Ko v OCamlu napišemo nekaj funkcij na seznamih, vidimo, da imajo dostikrat podobno obliko: imajo osnoven primer za prazen seznam ter rekurzivnega za sestavljen seznam. Na primer, vsoto izračunamo kot:

  vsota [a; b; c]
= vsota (a :: b :: c :: [])
= a + vsota (b :: c :: [])
= a + (b + vsota (c :: []))
= a + (b + (c + vsota []))
= a + (b + (c + 0))
= a + b + c

in definiramo kot:

let rec vsota =
  function
  | [] -> 0
  | glava :: rep -> glava + vsota rep
val vsota : int list -> int = <fun>

Zmnožek elementov seznama izračunamo kot:

  zmnozek [a; b; c]
= zmnozek (a :: b :: c :: [])
= a * zmnozek (b :: c :: [])
= a * (b * zmnozek (c :: []))
= a * (b * (c * zmnozek []))
= a * (b * (c * 1))
= a * b * c

in definiramo kot:

let rec zmnozek =
  function
  | [] -> 1
  | glava :: rep -> glava * zmnozek rep
val zmnozek : int list -> int = <fun>

Dolžino seznama izračunamo kot:

  dolzina [a; b; c]
= dolzina (a :: b :: c :: [])
= 1 + dolzina (b :: c :: [])
= 1 + (1 + dolzina (c :: []))
= 1 + (1 + (1 + dolzina []))
= 1 + (1 + (1 + 0))
= 3

in definiramo kot:

let rec dolzina =
  function
  | [] -> 0
  | _ :: rep -> 1 + dolzina rep
val dolzina : 'a list -> int = <fun>

Slikanje elementov seznama s funkcijo f izračunamo kot:

  map f [a; b; c]
= map f (a :: b :: c :: [])
= f a :: map f (b :: c :: [])
= f a :: (f b :: map f (c :: []))
= f a :: (f b :: (f c :: map f []))
= f a :: (f b :: (f c :: 1))
= [f a; f b; f c]

in definiramo kot:

let rec map f =
  function
  | [] -> []
  | glava :: rep -> f glava :: map f rep
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>

Splošni vzorec zajame funkcija fold_right, ki jo izračunamo kot:

  fold_right f [a; b; c] z
= fold_right f (a :: b :: c :: []) z
= f a (fold_right f (b :: c :: []) z)
= f a (f b (fold_right f (c :: []) z))
= f a (f b (f c (fold_right f [] z)))
= f a (f b (f c z))

in definiramo kot:

let rec fold_right f xs z =
  match xs with
  | [] -> z
  | x :: xs -> f x (fold_right f xs z)
val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b = <fun>

Funkcija sprejme tri argumente:

  • seznam xs,

  • vrednost z, ki jo funkcija vrne za prazen seznam, ter

  • funkcijo f, s katero glavo seznama zloži s sliko repa.

Na primer, vsota praznega seznama je \(0\), vsota sestavljenega pa je seštevek glave in vsote repa.

fold_right ( + ) [1; 2; 3; 4] 0
- : int = 10
fold_right ( * ) [1; 2; 3; 4] 1
- : int = 24

Za vajo lahko na enak način izrazite še ostale funkcije produkt, dolzina in preslikaj. Funkcija zlozi_desno je seveda zelo uporabna, zato je na voljo tudi v standardni knjižnici in sicer pod imenom List.fold_right.

Ni težko uganiti, da obstaja tudi funkcija, ki elemente zlaga v drugem vrstnem redu:

  fold_right f [a; b; c] z
= fold_right f (a :: b :: c :: []) z
= f a (fold_right f (b :: c :: []) z)
= f a (f b (fold_right f (c :: []) z))
= f a (f b (f c (fold_right f [] z)))
= f a (f b (f c z))

Definiramo jo kot:

  fold_left f z [a; b; c]
= fold_left f z (a :: b :: c :: [])
= fold_left f (f z a) (b :: c :: [])
= fold_left f (f (f z a) b) (c :: [])
= fold_left f (f (f (f z a) b) c) []
= f (f (f z a) b) c

na voljo pa je tudi kot List.fold_left.

List.fold_left (^) "X" ["A"; "B"; "C"]
- : string = "XABC"
List.fold_left (+) 0 [10; 20; 30]
- : int = 60
List.fold_left (fun xs x -> x :: xs) [] [1; 2; 3]
- : int list = [3; 2; 1]

Za funkcije, kjer vrstni red ni pomemben, kot je seštevanje, množenje, združevanje nizov, je bolje uporabiti fold_left, saj je ta učinkovitejši.

Repna rekurzija#

Rekli smo, da namesto zank v funkcijskem programiranju uporabljamo rekurzivne funkcije. Zato se moramo naučiti, kako take funkcije napišemo učinkovito.

Repni klici#

Pravimo, da je klic funkcije repen, če se izvede kot zadnji korak v definiciji funkcije. Najprej si oglejmo nasproten primer: funkcije, ki drugo funkcijo uporabijo v pomožnem izračunu:

let f x = 4 * x
let g x = 6 + f x
let h x = 3 * g x

Ker klic funkcije g v definiciji funkcije h ni repen, morajo funkcija h svoje delo (torej množenje s 3) odložiti na sklad (ki smo ga spoznali na začetku predmeta) in počakati na rezultat funkcije g, preden lahko nadaljuje z delom. Podobno mora funkcija g počakati na funkcijo f:

  h 2                (* h dela *)
= 3 * g 2            (* g dela, h čaka *)
= 3 * (6 + f 2)      (* f dela, g čaka, h čaka *)
= 3 * (6 + (4 * 2))  (* f dela, g čaka, h čaka *)
= 3 * (6 + 8)        (* g dela, h čaka *)
= 3 * 14             (* h dela *)
= 42

Zdaj pa si oglejmo še tri funkcije, v katerih so klici pomožnih funkcij repni:

let f x = 3 * x
let g x = f (6 + x)
let h x = g (4 * x)

V tem primeru lahko klicajoča funkcija ob klicu delo v celoti prepusti klicani funkciji, zato ni ničesar potrebno odlagati na sklad:

  h 2                (* h dela *)
= g (4 * 2)          (* h dela *)
= g 8                (* g dela *)
= f (6 + 8)          (* g dela *)
= f 14               (* f dela *)
= 3 * 14             (* f dela *)
= 42

Repno rekurzivne funkcije#

Repni klici so še posebej pomembni pri rekurzivnih funkcijah, pri katerih je število klicev lahko zelo veliko. Poglejmo si trapasto funkcijo, ki svoj argument zmanjšuje za ena ter hkrati povečuje rezultat:

let rec f x =
  if x = 0 then 0 else 1 + f (x - 1)
val f : int -> int = <fun>
f 3
- : int = 3

Tudi tu se klici kopičijo na skladu:

  f 3                  (* f dela *)
= 1 + f 2              (* f dela, f čaka *)
= 1 + (1 + f 1)        (* f dela, f čaka, f čaka *)
= 1 + (1 + (1 + f 0))  (* f dela, f čaka, f čaka, f čaka *)
= 1 + (1 + (1 + 0))    (* f dela, f čaka, f čaka *)
= 1 + (1 + 1)          (* f dela, f čaka *)
= 1 + 2                (* f dela *)
= 3

Če bi bil vhodni argument velik, bi to lahko vodilo do prekoračitve sklada (stack overflow). Za razliko od drugih jezikov, je v OCamlu dovoljena velikost sklada nastavljena precej visoko, kar je za večino primerov dovolj.

f 1000
- : int = 1000
f 100000
- : int = 100000
f 300000
Stack overflow during evaluation (looping recursion?).
Raised by primitive operation at f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36
Called from f in file "[63]", line 2, characters 27-36

Še bolje pa je, da funkcijo napišemo tako, da sklad ne raste. Če je rekurzivni klic funkcije repen, taki funkciji pravimo repno rekurzivna.

Pri pisanju repno rekurzivnih funkcij si običajno pomagamo s pomožnimi funkcijami, ki imajo dodaten argument, v katerem shranjujejo delno izračunani rezultat. Takemu argumentu dostikrat pravimo akumulator (ker nabira do sedaj izračunani rezultat). Zgornjo funkcijo f bi tako prevedli v ekvivalentno, vendar repno rekurzivno funkcijo f' kot:

let f' x =
  let rec aux acc x =
    if x = 0 then acc else aux (acc + 1) (x - 1)
  in
  aux 0 x
val f' : int -> int = <fun>
f' 1000
- : int = 1000
f' 100000000
- : int = 100000000

OCaml in tudi drugi funkcijski jeziki repne klice prepoznajo in jih optimizirajo tako, da jih na koncu v strojni kodi prevedejo v običajne skoke. Zato lahko repno rekurzivne funkcije kličemo na poljubno velikih argumentih in z veliko manjšo porabo pomnilnika. Za razliko od OCamla Python repnih klicev ne optimizira, saj zaradi lažjega odpravljanja napak želi ohraniti traceback, torej sled klicev, ki je vodila do dane točke v izvajanju:

def f(x, acc=0):
    if x == 0:
        return acc
    else:
        return f(x - 1, acc=acc + 1)
>>> f(1000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in f
  File "<stdin>", line 5, in f
  File "<stdin>", line 5, in f
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

Repno rekurzivne funkcije na seznamih#

Podobno moramo na repno rekurzijo paziti pri funkcijah na seznamih, saj so ti lahko zelo dolgi. Na primer, oglejmo si funkcijo za izračun vsote seznama, ki deluje tako, da izračuna vsoto repa, po tem pa rezultatu prišteje še glavo:

let rec vsota =
  function
  | [] -> 0
  | glava :: rep -> glava + vsota rep
val vsota : int list -> int = <fun>

Če izračunamo dolžino seznama [1; 2; 3; 4; ...], se bo ob vsakem elementu funkcija rekurzivno poklicala in svoje dotedanje delo odložila na sklad:

  vsota [1; 2; 3; 4; ...]
= 1 + vsota [2; 3; 4; ...]
= 1 + (2 + vsota [3; 4; ...])
= 1 + (2 + (3 + vsota [4; ...]))
= ...

Če funkcijo pokličemo na dovolj dolgem seznamu, bomo spet prekoračili sklad:

vsota (List.init 1000 (fun x -> x))
- : int = 499500
vsota (List.init 1000000 (fun x -> x))
Stack overflow during evaluation (looping recursion?).
Raised by primitive operation at vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37
Called from vsota in file "[71]", line 4, characters 28-37

Tudi tu si lahko pomagamo tako, da napišemo delno funkcijo z dodatnim argumentom, v katerem si podaja vsoto do sedaj pregledanih elementov.

let rec vsota' sez =
  let rec aux delna_vsota =
    function
    | [] -> delna_vsota
    | glava :: rep -> aux (delna_vsota + glava) rep
  in
  aux 0 sez
val vsota' : int list -> int = <fun>
  vsota' [1; 2; 3; 4; ...]
= aux 0 [1; 2; 3; 4; ...]
= aux (0 + 1) [2; 3; 4; ...]
= aux 1 [2; 3; 4; ...]
= aux (1 + 2) [3; 4; ...]
= aux 3 [3; 4; ...]
= aux (3 + 3) [4; ...]
= aux 6 [4; ...]
= ...

Kot vidimo, vsoto računamo sproti, zato sklad ne raste. Na ta način lahko brez težav seštejemo tudi zelo dolge sezname:

vsota' (List.init 1000000 (fun x -> x))
- : int = 499999500000

Podobno lahko prepišemo tudi druge funkcije. Na primer, pri računanju dolžine seznama bi si v akumulatorju nabirali do sedaj preštete elemente, za začetno vrednost akumulatorja pa bi si izbrali 0:

let rec dolzina =
  function
  | [] -> 0
  | _ :: rep -> 1 + dolzina rep  
val dolzina : 'a list -> int = <fun>
let dolzina' seznam =
  let rec aux acc =
    function
    | [] -> acc
    | _ :: rep -> aux (acc + 1) rep
  in
  aux 0 seznam
val dolzina' : 'a list -> int = <fun>
dolzina' [1; 2; 3; 4; 1]
- : int = 5
dolzina [1; 2; 3; 4]
- : int = 4

Pri funkciji map bi si nabirali že preslikane elemente, začeli pa bi s praznim seznamom:

let rec map f =
  function
  | [] -> []
  | glava :: rep -> f glava :: map f rep
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
let map' f seznam =
  let rec aux acc =
    function
    | [] -> List.rev acc
    | glava :: rep -> aux (f glava :: acc) rep
  in
  aux [] seznam
val map' : ('a -> 'b) -> 'a list -> 'b list = <fun>
map' (fun x -> 10 * x) [1; 2; 3; 4]
- : int list = [10; 20; 30; 40]

Tu moramo biti pozorni, da na koncu akumulator obrnemo na glavo, saj smo ga začeli sestavljati s prvim elementom, ki je tako končal na zadnjem mestu.

Nekatere funkcije na seznamih, na primer fold_left, so že naravno repno rekurzivne:

  fold_left f z [1; 10; 100]
= fold_left f z (1 :: 10 :: 100 :: [])
= fold_left f (f z 1) (10 :: 100 :: [])
= fold_left f (f (f z 1) 10) (100 :: [])
= fold_left f (f (f (f z 1) 10) 100) []
= f (f (f z 1) 10) 100

Medtem funkcija fold_right ni repno rekurzivna:

  fold_right f [1; 10; 100] z
= fold_right f (1 :: 10 :: 100 :: []) z
= f 1 (fold_right f (10 :: 100 :: []) z)
= f 1 (f 10 (fold_right f (100 :: []) z))
= f 1 (f 10 (f 100 (fold_right f [] z)))
= f 1 (f 10 (f 100 z))

Vaje#

Napišite spodaj opisane funkcije, ne da bi uporabljali funkcije iz standardne knjižnice. Kjer to kažejo primeri, napišite tudi repno rekurzivne različice z imenom ime_funkcije_tlrec.

Funkcija reverse#

Definirajte pomožno funkcijo za obračanje seznamov. Funkcija naj bo repno rekurzivna.

Funkcija repeat#

Funkcija repeat x n vrne seznam n ponovitev vrednosti x. Za neprimerne vrednosti n funkcija vrne prazen seznam.

let primer_repeat_1 = repeat "A" 5
val primer_repeat_1 : string list = ["A"; "A"; "A"; "A"; "A"]
let primer_repeat_2 = repeat "A" (-2)
val primer_repeat_2 : string list = []

Funkcija range#

Funkcija range naj sprejme število in vrne seznam vseh celih števil od 0 do vključno danega števila. Za neprimerne argumente naj funkcija vrne prazen seznam. Funkcija naj bo repno rekurzivna. Pri tem ne smete uporabiti vgrajene funkcije List.init.

let primer_range = range 10
val primer_range : int list = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

Funkcija map#

Funkcija map f list naj sprejme seznam list oblike x0; x1; x2; ... in funkcijo f ter vrne seznam preslikanih vrednosti, torej f x0; f x1; f x2; .... Pri tem ne smete uporabiti vgrajene funkcije List.map.

let primer_map_1 =
  let plus_two = (+) 2 in
  map plus_two [0; 1; 2; 3; 4]
val primer_map_1 : int list = [2; 3; 4; 5; 6]

Napišite še funkcijo map_tlrec, ki naj bo repno rekurzivna različica funkcije map.

let primer_map_2 =
  let plus_two = (+) 2 in
  map_tlrec plus_two [0; 1; 2; 3; 4]
val primer_map_2 : int list = [2; 3; 4; 5; 6]

Funkcija mapi#

Funkcija mapi naj bo ekvivalentna Python kodi:

def mapi(f, lst):
    mapi_lst = []
    index = 0
    for x in lst:
        mapi_lst.append(f(index, x))
        index += 1
    return mapi_lst

Pri tem ne smete uporabiti vgrajene funkcije List.mapi.

let primer_mapi = mapi (+) [0; 0; 0; 2; 2; 2]
val primer_mapi : int list = [0; 1; 2; 5; 6; 7]

Funkcija zip#

Funkcija zip naj sprejme dva seznama in vrne seznam parov istoležnih elementov podanih seznamov. Če seznama nista enake dolžine, naj vrne napako. Pri tem ne smete uporabiti vgrajene funkcije List.combine.

let primer_zip_1 = zip [1; 1; 1; 1] [0; 1; 2; 3]
val primer_zip_1 : (int * int) list = [(1, 0); (1, 1); (1, 2); (1, 3)]
let primer_zip_2 = zip [1; 1; 1; 1] [1; 2; 3; 4; 5]
Exception: Failure "Different lengths of input lists.".
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from zip in file "[95]", line 5, characters 34-45
Called from zip in file "[95]", line 5, characters 34-45
Called from zip in file "[95]", line 5, characters 34-45
Called from zip in file "[95]", line 5, characters 34-45
Called from unknown location
Called from Stdlib__Fun.protect in file "fun.ml", line 33, characters 8-15
Re-raised at Stdlib__Fun.protect in file "fun.ml", line 38, characters 6-52
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-150

Funkcija unzip#

Funkcija unzip je inverz funkcije zip, torej sprejme seznam parov (x0, y0); (x1, y1); ... in vrne par seznamov (x0; x1; ..., y0; y1; ...). Pri tem ne smete uporabiti vgrajene funkcije List.split.

let primer_unzip_1 = unzip [(0,"a"); (1,"b"); (2,"c")]
val primer_unzip_1 : int list * string list = ([0; 1; 2], ["a"; "b"; "c"])

Funkcija unzip_tlrec je repno rekurzivna različica funkcije unzip.

let primer_unzip_2 = unzip_tlrec [(0,"a"); (1,"b"); (2,"c")]
val primer_unzip_2 : int list * string list = ([0; 1; 2], ["a"; "b"; "c"])

Zanke#

Funkcija loop condition f x naj se izvede kot python koda:

def loop(condition, f, x):
    while condition(x):
        x = f(x)
    return x
let primer_loop = loop (fun x -> x < 10) ((+) 4) 4
val primer_loop : int = 12

Funkcija fold_left#

Funkcija fold_left_no_acc f list naj sprejme seznam x0; x1; ...; xn in funkcijo dveh argumentov f in vrne vrednost izračuna f(... (f (f x0 x1) x2) ... xn). V primeru seznama z manj kot dvema elementoma naj vrne napako.

let primer_fold_left_no_acc =
  fold_left_no_acc (^) ["F"; "I"; "C"; "U"; "S"]
val primer_fold_left_no_acc : string = "FICUS"

Funkcija apply_sequence#

Funkcija apply_sequence f x n naj vrne seznam zaporednih uporab funkcije f na vrednosti x do vključno n-te uporabe, torej [x; f x; f (f x); ...; fⁿ x]. Funkcija naj bo repno rekurzivna.

let primer_apply_sequence_1 = apply_sequence (fun x -> x * x) 2 5
val primer_apply_sequence_1 : int list = [2; 4; 16; 256; 65536; 4294967296]
let primer_apply_sequence_2 = apply_sequence (fun x -> x * x) 2 (-5)
val primer_apply_sequence_2 : int list = []

Funkcija filter#

Funkcija filter f list vrne seznam elementov list, pri katerih funkcija f vrne vrednost true. Pri tem ne smete uporabiti vgrajene funkcije List.filter.

let primer_filter = filter ((<)3) [0; 1; 2; 3; 4; 5]
val primer_filter : int list = [4; 5]

Funkcija exists#

Funkcija exists sprejme seznam in funkcijo, ter vrne vrednost true čim obstaja element seznama, za katerega funkcija vrne true in false sicer. Funkcija je repno rekurzivna. Pri tem ne smete uporabiti vgrajene funkcije List.find ali podobnih.

let primer_exists_1 = exists ((<) 3) [0; 1; 2; 3; 4; 5]
val primer_exists_1 : bool = true
let primer_exists_2 = exists ((<) 8) [0; 1; 2; 3; 4; 5]
val primer_exists_2 : bool = false

Funkcija first#

Funkcija first f default list vrne prvi element seznama, za katerega funkcija f vrne true. Če takšnega elementa ni, vrne default. Funkcija je repno rekurzivna. Pri tem ne smete uporabiti vgrajene funkcije List.find ali podobnih.

let primer_first_1 = first ((<) 3) 0 [1; 1; 2; 3; 5; 8]
val primer_first_1 : int = 5
let primer_first_2 = first ((<) 8) 0 [1; 1; 2; 3; 5; 8]
val primer_first_2 : int = 0