سؤال

Reading the comments to this blog post made me realize I don't know much about some really interesting functional mechanisms between languages like Haskell, OCaml and Standard ML. I'd love a high-level overview not of syntax but of the general concept of what these 3 things are.

هل كانت مفيدة؟

المحلول

Since both are in OCaml, We can explore the difference between generative and applicative functors easily:

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]

Applicative functors are the default in OCaml, they are more appropriate when a functor application is pure (which is, arguably, the most common case). Generative functors are available since 4.02.

Generative functors are the default in SML, they are more appropriate when a functor is impure (or when doing type shenanigans). AFAIK, applicative functors are not available in any SML dialects.

In practice in OCaml, generative functors are used in general in combination with first class modules to have functions that generates a fresh type at each application. This has various use cases (heterogeneous maps, emulating singletons types, ...). In particular, this sentence from the manual is of importance: "As a side-effect of this generativity, one is allowed to unpack first-class modules in the body of generative functors."

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top