This is the value restriction. first
is not a value, it's a function application.
To get a fully polymorphic version, use eta expansion:
# let left x y = x;;
val left : 'a -> 'b -> 'a = <fun>
# let first a b = List.fold_right left a b;;
val first : 'a list -> 'a -> 'a = <fun>
As @ivg points out, this is a commonly asked OCaml question.
Update
Here's a function application that's unsafe to generalize:
# let f x = ref x;;
val f : 'a -> 'a ref = <fun>
# f [];;
- : '_a list ref = {contents = []}
If you pretend that the result has the type 'a list ref
you can make the code go wrong (I tried it).
Here's a partial application that's unsafe to generalize:
# let g x = let z = ref x in fun () -> z;;
val g : 'a -> unit -> 'a ref = <fun>
# g [];;
- : unit -> '_a list ref = <fun>
If you pretend that the result has type unit -> 'a list ref
you can make this code go wrong (I tried it).