I try to figure out the type of the OCaml function below:
let subst = fun x -> fun y -> fun z -> x z (y z)(* Or more concisely *)let subst x y z = x z (y z)
Here's my derivation.
Step 1, assume the type of x, y, z
, and the output value of subst
as below:
x: 'ay: 'bz: 'csubst: 'a -> 'b -> 'c -> 'd
Step 2, notice that both x
and y
can be applied to z
, so we get: (two more types are introduced, 'e
and 'f
)
'a = 'c -> 'e'b = 'c -> 'f(y z):'f
Step 3, notice that (x z)
can be applied to (y z):'f
, so we get:
(x z) : 'f -> 'd (* note that 'd is the type of the final output value *)
Step 4, recall that we have x : 'c -> 'e
, and the type of x
's output is unique, so with step 3 we get:
'e = 'f -> 'd
Step 5, expand all and we get:
'a = 'c -> 'e = 'c -> 'f -> 'd (* type of x *)'b = 'c -> 'f (* type of y *)'c (* type of z *)
Finally, the type of the function subst
is:
subst: ('c -> 'f -> 'd) -> ('c -> 'f) -> 'c -> 'd ---------------- ----------- --- ------- x y z output
Replace c, f, d
with a, b, c
, we get:
subst: ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c
I am new to type theory and functional programming.
Not sure if my derivation is optimal or even correct.
Could anyone provide some insight?
And I am wondering where I can learn the systematic/canonical way for such type inference problem.
Thanks.