Why does it become monomorphic?

Why is mono only monomorphic here ?

let id x = x;;
let apply f x = f x;;
let mono = apply id;;
let poly x = apply id x;;

val id : 'a -> 'a = <fun>
val apply : ('a -> 'b) -> 'a -> 'b = <fun>
val mono : '_weak1 -> '_weak1 = <fun>
val poly : 'a -> 'a = <fun>

# mono 1;;
- : int = 1
# mono;;
- : int -> int = <fun>

Short answer is “the value restriction”.
For the long answer, you might want to read this chapter of the manual.

4 Likes

For an example that uses your type and that would turn out problematic without this behaviour, consider the following code:

let fake_apply f =
  let r = ref None in
  fun x ->
    match !r with
    | Some y -> f y
    | None -> begin r := Some x; f x end
let poly x = fake_apply List.hd x
let x = poly [0; 1]
let y = poly ["a"; "b"]

val fake_apply : ('a -> 'b) -> 'a -> 'b = <fun>
val poly : 'a list -> 'a = <fun>
val x : int = 0
val y : string = "a"

So far so good. But now imagine this worked:

let mono = fake_apply List.hd
let x = mono [0; 1]
let y = mono ["a"; "b"]

Convince yourself of the following: if mono is allowed to have type 'a list -> 'a, y will be typed as string, but its value is going to be 0.

2 Likes

After reading various texts and toying in the REPL I think I understand better.

It is non trivial to learn OCaml so far

Thanks :hugs:

1 Like