I'm confused about let polymorphism in OCaml.
Consider the following code:
A:
let f = (fun v -> v) in
((f 3), (f true))
B:
let f = (fun v -> v) in
((fun g ->
let f = g in
f) f)
C:
let f = (fun v -> v) in
((fun g ->
let f = g in
((f 3), (f true))) f)
For A and B, there is no problem. But for C, OCaml reports error:
Error: This expression has type bool but an expression was expected of type
int
So for A, when evaluating ((f 3), (f true)), f's type is 'a -> 'a,
for B, when evaluating let f = g in f, f's type is 'a -> 'a.
But for C, when evaluating ((f 3), (f true)), f's type is int -> int.
Why C's f doesn't have type 'a -> 'a?
I have difficulty in understanding the implementation of OCaml's
let polymorphism, I'll appreciate it a lot if anyone can give a concise
description of it with respect to the question.
Your code is unnecessarily confusing because you're using the same name
ffor two different things in B and also two different things in C.Inside C you have this function:
Again this is unnecessarily complicated; it's the same as:
The reason this isn't allowed is that it only works if
gis a polymorphic function. This requires rank 2 polymorphism, i.e., it requires the ability to define function parameters that are polymorphic.I'm not exactly sure what you're trying to do, but you can have a record type whose field is a polymorphic function. You can then use this record type to define something like your function:
The downside is that you need to pack and unpack your polymorphic function.
As a side comment, your example doesn't seem very compelling, because the number of functions of type
'a -> 'ais quite limited.