ファンクタはストラクチャからストラクチャへの「関数」であり、パラメータ化されたストラクチャを表現するために使用されます。
例えば、ストラクチャ B
によりパラメータ化された ストラクチャ A
は、単純に仮引数 B
(ストラクチャ B
のシグネチャを持つことが期待される) を持ち、実際のファンクタ A
を返すファンクタ F
として表現されます。
そのようなファンクタ F
があるとき、 F
に対していくつかの B
の実装 B1
... B
を適用することで、対応するストラクチャ n
A1
... A
が得られます。
n
具体的な例として、ソート済リストとして実装した集合を考えます。 ここで考える集合は集合要素の型と、集合要素の型の上の順序付け関数でパラメータ化されています。
#
type comparison = Less | Equal | Greater;;
type comparison = Less | Equal | Greater
#
module type ORDERED_TYPE = sig type t val compare: t -> t -> comparison end;;
module type ORDERED_TYPE = sig type t val compare : t -> t -> comparison end
#
module Set = functor (Elt: ORDERED_TYPE) -> struct type element = Elt.t type set = element list let empty = [] let rec add x s = match s with [] -> [x] | hd::tl -> match Elt.compare x hd with Equal -> s (* x is already in s *) | Less -> x :: s (* x is smaller than all elements of s *) | Greater -> hd :: add x tl let rec member x s = match s with [] -> false | hd::tl -> match Elt.compare x hd with Equal -> true (* x belongs to s *) | Less -> false (* x is smaller than all elements of s *) | Greater -> member x tl end;;
module Set : functor (Elt : ORDERED_TYPE) -> sig type element = Elt.t type set = element list val empty : 'a list val add : Elt.t -> Elt.t list -> Elt.t list val member : Elt.t -> Elt.t list -> bool end
このように定義したファンクタ Set
を ORDERED_TYPE
を実装したストラクチャに適用することにより、その型に対する集合演算を得ることが出来ます。
#
module OrderedString = struct type t = string let compare x y = if x = y then Equal else if x < y then Less else Greater end;;
module OrderedString : sig type t = string val compare : 'a -> 'a -> comparison end
#
module StringSet = Set(OrderedString);;
module StringSet : sig type element = OrderedString.t type set = element list val empty : 'a list val add : OrderedString.t -> OrderedString.t list -> OrderedString.t list val member : OrderedString.t -> OrderedString.t list -> bool end
#
StringSet.member "bar" (StringSet.add "foo" StringSet.empty);;
- : bool = false