コード共有はデータ型の宣言についても適用できます。 例えば、なじみ深い多相データ型 list0 は次のように宣言されます:
より正確には list0 は型コンストラクタです。 型 T が与えられた時、型 T を要素とするリストである型 list0(T) を作ることができます。 例えば list0(char) は文字のリストで、 list0(int) は整数のリスト、list0(list0(int)) は整数のリストを要素とするリスト、などです。 関数テンプレートや多相関数の主な必要性は多相データ型の可用性から大いに生じています。 例として、関数テンプレート list0_length は与えられたリストの長さを計算するよう、次のように実装されます:fun{a:t@ype} list0_length (xs: list0 a): int = ( case+ xs of | list0_cons (_, xs) => 1 + list0_length<a> (xs) | list0_nil () => 0 ) (* end of [list0_length] *)
もう一つの多相データ型の一般的な使い方 option0 は次のような宣言です:
option0 の典型的な使い方はエラーの取り扱いです。 整数の除算関数を実装しようとしていて、0 で除算してしまった時でも関数が返ってくることを保証したくなったとしましょう。 これは次のようにすれば可能です:fun divopt ( x: int, y: int ) : option0 (int) = if y != 0 then option0_some{int}(x/y) else option0_none((*void*)) // end of [divopt]
fun{ a:t@ype } list0_last ( xs: list0 a ) : option0 (a) = let // fun loop (x: a, xs: list0 a): a = ( case+ xs of | list0_nil () => x | list0_cons (x, xs) => loop (x, xs) ) (* end of [loop] *) // in case+ xs of | list0_nil () => option0_none((*void*)) | list0_cons (x, xs) => option0_some{a}(loop (x, xs)) end // end of [list0_last]