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>

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.