Obviously, 'a is bound by its first occurrence in the type annotation,
here. Can someone explain this behavior?
In a type annotation, the scope of variables is only the type annotation. So in your example the ['a] in the annotation of [a_to_opt] and the ['a] in the annotation of [None] are distinct. To refer to the same type, you need to use a local abstract type:
let rec a_to_opt : type a. (a -> a option) = fun x -> (None : a