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, and z, and the output value of subst as below:
x: 'a
y: 'b
z: 'c
subst: '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, actually I am a bit uncertain about the expansion of 'e to 'f -> 'd *)
'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. I'm not sure if my derivation is optimal or even correct. Could anyone provide some insight?
Is there any better solution?