Note that OCaml has both applicative and generative functors nowadays.
Applicative functors are useful when different applications of the same functor with the same entry should yield the same types.
A good example is the set functor, when you write
module Int_set = Set.Make(Int)
the resulting type Int_set.t is “the” type of sets of Int.t integers ordered with the Int.compare order.
Thus, if two libraries defines this module, there is no reason to consider that the sets of one library should be incompatible with the sets of the other library.
Contrarily, generative functor always create completely fresh types. Consider for instance an Make_id module:
module Make_id (): sig
type t
val create: unit -> t
end = struct
type t = int
let unique_stamp = Atomic.make 0
let create x = Atomic.fetch_and_add unique_stamp 1
end
Then applying the functor yield a new identifier type:
module First_ids = Make_id ()
module Second_ids = Make_id ()
The two identifier types are then guaranteed to be distinct, which is important to ensure that we never generate equal identifiers twice. This is common phenomenon as soon as the functor generate some global mutable state in the generated module.