Can somebody explain step by step type inference in following F# program:
let rec sumList lst =
match lst with
| [] -> 0
| hd :: tl -> hd + sumList tl
I specifically want to see step by step how process of unification in Hindley Milner works.
Fun stuff!
First we invent a generic type for sumList:
x -> yAnd get the simple equations:
t(lst) = x;t(match ...) = yNow you add the equation:
t(lst) = [a]because of(match lst with [] ...)Then the equation:
b = t(0) = Int;y = bSince 0 is a possible result of the match:
c = t(match lst with ...) = bFrom the second pattern:
t(lst) = [d];t(hd) = e;t(tl) = f;f = [e];t(lst) = t(tl);t(lst) = [t(hd)]Guess a type (a generic type) for
hd:g = t(hd);e = gThen we need a type for
sumList, so we’ll just get a meaningless function type for now:h -> i = t(sumList)So now we know:
h = f;t(sumList tl) = iThen from the addition we get:
Addable g;Addable i;g = i;t(hd + sumList tl) = gNow we can start unification:
t(lst) = t(tl)=>[a] = f = [e]=>a = et(lst) = x = [a] = f = [e];h = t(tl) = xt(hd) = g = i/\i = y=>y = t(hd)x = t(lst) = [t(hd)]/\t(hd) = y=>x = [y]y = b = Int/\x = [y]=>x = [Int]=>t(sumList) = [Int] -> IntI skipped some trivial steps, but I think you can get how it works.