Poiché entrambi sono in OCaml, possiamo esplorare facilmente la differenza tra i generatori generativi e applicativi:
module type S = sig type t end
module M = struct type t = int end
(* An Applicative functor. *)
module F (M : S) = struct
type t = Foo of M.t list
end
module F1 = F(M)
module F2 = F(M)
(* M1 = M2 => F(M1).t ≡ F(M2).t
This works.
*)
let x : F1.t = F2.Foo [3]
(* A Generative functor. Note the () argument *)
module F (M : S) () = struct
type t = Foo of M.t list
end
module F1 = F(M)()
module F2 = F(M)()
(* This doesn't work anymore ! F1.t ≠ F2.t *)
let x : F1.t = F2.Foo [3]
I funtori applicativi sono quelli predefiniti in OCaml, sono più appropriati quando un'applicazione di un functor è pura (che è, probabilmente, il caso più comune). I funtori generativi sono disponibili dalla 4.02 .
I funtori generativi sono i valori predefiniti in SML, sono più appropriati quando un funtore è impuro (o quando si fa il tipo shenanigans). AFAIK, i funtori applicativi non sono disponibili in qualsiasi dialetto SML.
In pratica in OCaml, i funtori generativi sono usati in generale in combinazione con moduli di prima classe per avere funzioni che generano un nuovo tipo per ogni applicazione. Questo ha vari casi d'uso (mappe eterogenee, tipi di singleton emulatori, ...). In particolare, questa frase del manuale è importante: "Come effetto collaterale di questa generatività, è permesso disfare i moduli di prima classe nel corpo dei funtori generativi."