プログラミング in OCaml メモ
『プログラミング in OCaml』を呼んでて、ファンクターのところが難しかったので、頭を整理してみた。
ファンクターとは?
「要素型に関するモジュール」から「その型を要素とする集合モジュール」を生成する関数
例) Setモジュール(集合モジュール)には、Make という名前のファンクターがある。
このファンクターには、mem、add、inter、elements など、多くの関数が定義されており、Set.Make というファンクターでモジュールを作成することで利用可能である。
ファンクターを使う
Setモジュールを利用するためには、
1) 集合要素の型 t の定義
2) その型の大小比較の関数 compare : t -> t -> int
のふたつを含むモジュールが必要である。
方法1:
具体的には、以下のようなかたちで、自分の望む Set モジュールを手に入れることができる。
# module IntSet = Set.Make (struct
type t = int
let compare i j = i - j
end);;
# moduke 新モジュール名 = ファンクター名 ( モジュール式 )
方法2:
# module OrgInt =
struct
type t = int
let compare i j = i - j
end;;
# module IntSet = Set.Make (OrgInt);;
これは、以下のように、型を定義したモジュールを作成してからファンクターの引数に与えても良い。
ただ、コンパイラからの応答に若干の違いが出る。
方法1 の場合
module IntSet :
sig
type elt = int
type t
…
方法2 の場合
module IntSet :
sig
type elt = int
type t = Set.Make(OrgInt).t
...
こちらの場合は、ファンクターの名前、もとのモジュールの名前が現れる。
ただ、作成したモジュール IntSet を使って、以下の式を評価した場合、方法1、方法2のどちらでも、コンパイラからの応答は同じである。
let my = IntSet.add 2 (IntSet.add 1 IntSet.empty);;
(* val my : IntSet.t = <abstr> *)
IntSet.elements my;;
(* - : int list = [1; 2] *)