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 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₃
,τ₁ = α list
inτ₂ = τ₃
.- 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
.