Why does the compiler stop complaining about `type unit` in this case?

ocaml

Solution

If compiler does not give Warning 10, it means it thinks f() returns unit, doesn't it?

Obviously, if the compiler gives `f2` the type `(unit -> 'a) -> int`, that means it thinks `f` returns `'a`.

What would you do in the compiler's place?

Would you warn that `f2` may be applied to some functions that return non-unit results, although it may never actually be applied thus?

Would you give `f2` the type `(unit -> unit) -> int` and make it less useful, forcing it to be used only with functions that return `()`?

Would you invent a complicated system of postponed warnings where `f2` has type `(unit -> 'a) -> int` but produces an additional warning at compile-time if it is applied to a function that does not return `()`? Would you make this system work across modules (the postponed warnings of a function would have to be part of the module signatures)?

Warnings are only helpful hints, not guarantees. When in doubt, not emitting the warning is the usual solution (and nearly all compilers adopt this solution, not just the OCaml compilers).

Problem

If I do `let f1 x = x; x+1`, compiler will complain: `Warning 10: this expression should have type unit.` If I do `let f2 f = f(); 5`, compiler will give `val f2 : (unit -> 'a) -> int = <fun>`. Questions - The type system infers that `f` is a function which take `unit` as parameter and returns `'a`. But if it returns `'a`, why the compiler does not give `Warning 10`? - If compiler does not give `Warning 10`, it means it thinks `f()` returns `unit`, doesn't it? Then why it give `'a` as the return type?

Original source