Rešitve
Izpeljava tipov
Za vsakega od naslednjih izrazov izpeljite njegov glavni tip, ali ugotovite, da ga nima. Nato preverite odgovor še v OCamlu.
Naloga
Izpeljite glavni tip izraza
fun x -> fun y -> (x, y, y)
Rešitev
Uvedemo nov parameter α in zabeležimo x : α. Funkcija ima tip α → β, kjer je β tip izraza fun y -> (x, y, y).
Tip izraza fun y -> (x, y, y): uvedemo nov parameter δ in zabeležimo y : δ. Tip izraza (x, y, y) je tako α × δ × δ. Funkcija fun y -> (x, y, y) ima torej tip δ → α × δ × δ. Dobimo enačbo β = δ → α × δ × δ.
V tipu α → β zamenjamo β ↦ δ → α × δ × δ, da dobimo glavni tip izraza:
α → δ → α × δ × δ
Naloga
Izpeljite glavni tip izraza
fun f -> fun g -> f (g 42)
Rešitev
Uvedemo nov parameter α in zabeležimo f : α. Funkcija ima tip α → β, kjer je β tip izraza fun g -> f (g 42).
Tip funkcije fun g -> f (g 42): uvedemo nov parameter γ in zabeležimo g : γ. Funkcija ima tip γ → δ, kjer je δ tip izraza f (g 42). Dobimo enačbo β = γ → δ.
Tip izraza f (g 42) je δ, zato mora imeti funkcija f tip ε → δ, kjer je ε tip izraza g 42. Dobimo enačbo α = ε → δ.
Tip izraza g 42 je ε, zato mora imeti funkcija g tip int → ε. Dobimo enačbo γ = int → ε.
Imamo naslednje enačbe:
α = ε → δ
β = γ → δ
γ = int → ε
Upoštevamo definicijo γ:
α = ε → δ
β = int → ε → δ
In dobimo glavni tip celega izraza α → β = (ε → δ) → (int → ε) → δ.
Naloga
Izpeljite glavni tip izraza
if 3 < 5 then (fun x -> x) else (fun y -> (y, y))
Rešitev
Tip lahko izpeljemo po kosih: posebej obravnavamo pogoj 3 < 5, kjer preverimo, da je tip
bool, nato pa izpeljemo tipa obeh vej in ju izenačimo.
Izraz 3 < 5 res ima tip bool, ker 3 in 5 imata tip int in < res vrne bool.
Tip funkcije fun x -> x: uvedemo nov parameter α in zabeležimo x : α. Nato izpeljemo tip
izraza x, ki je seveda α. Torej ima fun x -> x tip α → α.
Tip funkcije fun y -> (y, y): uvedemo nov parameter β in zabeležimo y : β. Nato
izpeljemo tip izraza (y, y). To je urejeni par, obe komponenti imata tip β, zato je
tip urejenega para (y, y) enak β × β. Torej ima fun y -> (y, y) tip β → β × β.
Izenačimo tipa obeh vej:
(α → α) = (β → β × β)
To je tudi edina enačba, ki jo moramo rešiti. Enačbo razbijemo na dve preprostejši enačbi:
α = β
α = β × β
Prva enačba nam da rešitev α ↦ β, ki jo upoštevamo v drugi enačbi:
β = β × β
Ta enačba nima rešitve, ker se β pojavi na desni strani. Končni odgovor: izraz nima tipa.
Naloga
Izpeljite glavni tip rekurzivne funkcije
let rec f x = (if x = 0 then 1 else x * f (x - 1))
Rešitev
Uvedemo parameter α in zabeležimo f : α.
Izraz fun x -> if x = 0 then 1 else x * f (x - 1) ima tip β → γ, pri čemer zabeležimo x : β in enačbo α = β → γ. Nato obravnavamo izraz if x = 0 then 1 else x * f (x - 1).
Iz pogoja dobimo enačbo β = int.
Tip izraza x * f (x - 1): izraz x - 1 ima tip int, zato mora imeti f tip int → γ. Dobimo enačbo α = int → γ. Po drugi strani mora zaradi množenja imeti izrazf (x - 1) tip int, torej dobimo γ = int. Preveriti moramo še, da imata obe veji pogojnega stavka isti tip in da ima pogoj x = 0 res tip bool.
Glavni tip α celega izraza je tako int → int.
Naloga
Izpeljite glavni tip funkcije map:
let rec map f l =
match l with
| [] -> []
| x :: xs -> f x :: map f xs
Navodilo: uporabite pravilo za rekurzivne funkcije, ter pravila za sezname in match:
prazen seznam
[]ima tipα list, kjer jeαnov parametersestavljen seznam
e₁ :: e₂:- izpeljemo tip
τ₁izrazae₁in dobimo enačbeE₁ - izpeljemo tip
τ₂izrazae₂in dobimo enačbeE₂
Tip
e₁ :: e₂jeτ₁ list, z enačbamiE₁,E₂inτ₂ = τ₁ list.- izpeljemo tip
izraz
match e₁ with [] -> e₂ | x :: xs -> e₃:- izpeljemo tip
τ₁izrazae₁in dobimo enačbeE₁ - izpeljemo tip
τ₂izrazae₂in dobimo enačbeE₂ - uvedemo nov parameter
α, zabeležimox : αinxs : α list, izpeljemo tipτ₃izrazae₃in dobimo enačbeE₃
Tip izraza
match e₁ with [] -> e₂ | x :: xs -> e₃jeτ₂z enačbamiE₁,E₂,E₃,τ₁ = α listinτ₂ = τ₃.- izpeljemo tip
Rešitev
Tip map označimo z α, tip f z β in l z γ. Nato izračunamo tip izraza match.
Prvi primer ima tip δ list, pri čemer je δ nov parameter.
Za drugi primer moramo izračunati tip izraza f x :: map f xs, pri čemer uvedemo nov parameter ε in zabeležimo x : ε in xs : ε list. Tip izraza f x označimo s φ₁ in zapišemo enačbo β = ε → φ₁. Tip izraza map f xs označimo s φ₂ in zapišemo enačbo α = β → ε list → φ₂. Tip celotnega izraza je φ₁ list, pri čemer mora veljati še φ₂ = φ₁ list.
Tip izraza match je torej φ₂, pri čemer morata veljati še enačbi γ = ε list in δ list = φ₁ list.
α = β → ε list → φ₂
β = ε → φ₁
δ list = φ₁ list
φ₂ = φ₁ list
Iz teh enačb dobimo tip funkcije map: α = (ε → φ₁) → ε list → φ₁ list.