これに対するコメントを読んで ブログ投稿 私はHaskell、OCaml、StandardMLのような言語間のいくつかの本当に興味深い機能メカニズムについてあまり知らないことに気づきました。構文ではなく、これら3つのことの一般的な概念の概要を説明したいと思います。
どちらもOCamlに含まれているため、生成ファンクターとアプリケーションファンクターの違いを簡単に調べることができます。
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]
適用可能なファンクターはOCamlのデフォルトであり、ファンクターアプリケーションが純粋な場合(おそらく最も一般的なケース)に適しています。生成ファンクターが利用可能です 4.02以降 。
生成ファンクターはSMLのデフォルトであり、ファンクターが不純な場合(またはタイプシェナニガンを実行する場合)に適しています。 AFAIK、アプリケーションファンクターはどのSML方言でも使用できません。
OCamlの実際には、生成ファンクターは一般にファーストクラスのモジュールと組み合わせて使用され、各アプリケーションで新しい型を生成する関数を持っています。これにはさまざまなユースケースがあります(異種マップ、シングルトンタイプのエミュレートなど)。特に、マニュアルのこの文は重要です。「この生殖性の副作用として、生成機能の本体でファーストクラスのモジュールを解凍することが許可されています。」