Unions
タグつきユニオン型もしくはバリアント型と呼ばれるものを導入する。ユニオン型はプログラム上の至るところに現れ、listなどもこの例であると考えることができる。ユニオン型の例としてbinary tree(二分木)を定義する。binary treeはNodeとLeafでできている。Nodeは内部にさらにbtreeを持っている。Nodeの各要素が'a型のbynary treeは以下のように定義できる。
# type 'a btree = Node of 'a * 'a btree * 'a btree | Leaf;; type 'a btree = Node of 'a * 'a btree * 'a btree | Leaf場合わけがバーチカルライン("|")でされている。書く場合にはそれぞれ名前がつけられており(Node,Leaf)、これらはコンストラクタと呼ばれる。コンストラクタは大文字から始まらなくてはならない。これらコンストラクタは値から非連結なunionを作る関数と見なすこともできる。
Node : ('a * 'a btree * 'a btree) -> 'a btreebtreeを使う例を見てみると、
# Leaf;; - : 'a btree = Leaf # Node(1, Leaf, Leaf);; - : int btree = Node (1, Leaf, Leaf)つまりunion型とは"条件のうちの一つを値としてとるような型"と見なすことができる。複数あるコンストラクタのうちどのデータ構造が選ばれるかはコンパイル時に決定されず、実行時にどのコンストラクタが使われたかがチェックされる。つまりunion型を用いることによりOcamlでdynamic typing(実行時型付け)を導入することができる。
また、union型の内部の値を扱うにはパターンマッチングを用いる。以下はbinary tree中のNodeの数を数えるプログラムである。
# let rec cardinality = function Leaf -> 0 |Node (_ , left , right ) -> cardinality left + cardinality right + 1;; val cardinality : 'a btree -> int = <fun> # cardinality (Node (1, Node ( 2, Leaf, Leaf) , Leaf));; - : int = 2
buit-in unions
実は今まで見てきたデータ型の中でunion型と見なせるものもある。# type bool = true | false;;bool型は大文字から始まってるけれども。
# type 'a list = [] | :: of 'a * 'a list;;bool型よりもさらに強引な書き方。[1 ; 2; 3]のような書き方はsyntax suger(糖衣構文)というやつです。