ジェネリック型の概要
プログラミングをしていると、型は違うけれども処理内容が非常に似ている関数や、データ構造を作りたい時があります。そんなときに使用するのがジェネリック(または、ジェネリクス)と呼ばれる機能です。ジェネリックはC++のテンプレート機能のようなものです。関数やクラスなどに "型" をパラメータとして渡し、それらのデータ型をいじることなくタイプセーフなデータ構造(または、処理構造)を定義することができます。たとえば、.NET の List<'T>型 などが有名です。
ジェネリックの型パラメータ(= ジェネリック制約 / ジェネリックコンストラクト)には、少なくとも1つの型パラメータが含まれています。ジェネリック関数やジェネリック型を使用すると、型ごとにわざわざコードを繰り返し記述しなくとも、さまざまな型で動作するコードを記述できます。F#プログラミングにおいては多くの場合、コンパイラの型推論と自動ジェネリック化メカニズムによって、暗黙的にジェネリックとして推論されるため、コードをジェネリック化しやすくなっています。
明示的なジェネリック定義
明示的にジェネリック関数やジェネリック型を宣言する場合、型パラメータを関数名、または型名の後ろに山カッコに囲んで指定します。また、型パラメータはアポストロフィ(= ') で始まらなければなりません。
型パラメータ以外は、非ジェネリック型となんら変わりません。通常の実装をするだけで、さまざまな型に対応することができます。
暗黙的なジェネリック定義
F#コンパイラがコード内の型を推論するとき、ジェネリックにできる関数は自動的にすべてジェネリック型として扱われます。型を明示的に指定することによって、自動ジェネリック化を回避することも可能です。 次のサンプルの、makeList関数 と そのパラメータ はいずれもジェネリックとして明示的に宣言していませんが、F#コンパイラによって自動的にジェネリック型となっています。