System output of function's type inference looks like missing ()

# let compose f g = function x -> f (g x);;
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>

I would like to know why the last two types are not surrounded by (), isn’t it a returning a function. I am seeing the two parameters, which are functions are each surrounded by ().

The function arrow -> is right-associative, meaning that a -> b -> c -> d is the same as a -> (b -> (c -> d)). So the type of compose shown is the same as

val compose : ('a -> 'b) -> ('c -> 'a) -> ('c -> 'b)

This right-associativity is handy because in OCaml as in other languages inspired by lambda calculus, functions are curried: in principle, there are only functions of one argument; a function of two arguments is seen as a function that returns a function; and so on for higher numbers of arguments.

Of course, for efficiency reasons, at the level of the generated executables functions of several arguments do exist, but OCaml lets you manipulate them as the theory dictates (e.g. partially applying them).