最小のクラス

クラスとはデータと関数の集合で オブジェクト指向プログラミングでは 基本的なデータ構造です。 クラスの定義は以下のようになります。
クラスの定義
type クラス名 [ パターン ] [ as 識別子 ] = class 継承宣言 let式 [要素型定義]* end
class〜endの中身は後回しにして まずは最小のクラスを宣言してみます。
最小のクラス
type Minimum = class end;;
これは、フィールドもメンバ関数も何も持っていないクラスMinimumの定義です。 このままでは何の役にもたたないので 次にこれにフィールドを追加していきますが クラスからオブジェクトを作るための コンストラクタの定義に2種類の方法があります。

明示的なコンストラクタ

コンストラクタとは、クラスをインスタンス化してオブジェクトを作る際に 初期化をするために呼ばれる関数のことです。 F#では、2種類のコンストラクタの記述の仕方がありますが まずは例を挙げてみます。
明示的なコンストラクタを用いるクラス宣言
type Explicit = class
    val a : int
    new (data) = {a = data;}
    end;;
let ex = new Explicit(10);;
System.Console.Write(ex.a);;
明示的なコンストラクタを用いるクラス宣言では フィールドの宣言にvalを用います。 また、newから始まる行がコンストラクタと呼ばれるものです。 ここは若干複雑なので、簡略化した構文を述べると次のようになります。
簡略化したコンストラクタ定義
new パターン [as 識別子] = {[識別子=式 ;]*} [then 式]
上の例ではdataが仮引数に相当するパターンで aの値をdataで初期化しています。 具体的には、new Explicit(10)というコンストラクタ呼び出しによって dataに10という値が割り当てられ、 それを用いてaに10が割り当てられています。 また、valを用いて宣言した変数は オブジェクトにドットをつけた後、フィールド名とすることで アクセスすることが出来ます。 コンストラクタでもう少し複雑な処理を行ってみたのが次の例です。 このプログラムでは、オブジェクトの生成後に処理は行っていませんが オブジェクト生成時に処理を行うことで、 上記のプログラムと同じ結果が得られます。
コンストラクタでの処理
type Explicit = class
    val a : int
    new (data) as this = {a = data;}
        then System.Console.Write(this.a)
    end;;
let ex = new Explicit(10);;
コンストラクタ内で初期化以外の処理をする際には 初期化が終わった後にthen 式と続けます。 また、コンストラクタ内で自分のフィールドの値を参照するためには asキーワードを用いて、自分をどの名前で参照するかを決めます。 この例では自分自身の参照をthisと指定し this.aという部分でフィールドaにアクセスしています。

暗黙的なコンストラクタ

クラスを利用するにあたって、 暗黙的なコンストラクタを用いる方法もあります。 これは、明示的なコンストラクタの後からF#に追加された機能です。 暗黙的なコンストラクタを用いるには クラス名に続いてパターンを指定します。 また、クラス内で使用する変数の宣言にはletを用います。
暗黙のコンストラクタを用いるクラス宣言
type Implicit(x:int) = class
    let a = x;
    end;;
let im = new Implicit(10);;
//System.Console.Write(im.a);; //エラー
こうしてletで定義した値は、クラスの外部からは参照できません。 この方式でクラスを使う際は 値を参照するためのメンバ関数などを用いることになると思います。 もし、明示的なフィールドの宣言が使いたい場合は DefaultValueという属性を用いて次のようにします。 また、必ずmutableをつけなければなりません。
明示的なフィールドの利用
type Implicit(x:int) = class
    let a = x;
    [<DefaultValue>]
    val mutable x : int
    end;;
let im = new Implicit(10);;
System.Console.Write(im.x);;
こうして宣言したフィールドは0に相当する物で初期化されます。 (例えば文字列なら"") これで、xの値をクラスの外からアクセスできるようになりました。 余談ですが、継承にまつわる問題として 以下のような記事があるみたいです。 これについて私はあまり理解出来ていないのですが F#ではどうなのでしょうね
参考:Inheritance is not subtyping問題
あるクラスを継承したクラスが
継承元のクラスの部分型にならないことがある、という問題のこと。
OCamlではこういうことが起こりうるようです。
最後に、メンバの定義の部分の構文についてまとめておきます。
メンバの定義
要素型定義 := | フィールド定義 | メンバ定義 | インターフェース定義 フィールド定義 :=  | [static] [mutable] 識別子 : 型名 メンバ定義 := | [ static ] member メンバ束縛 | (override|default) メンバ束縛 | コンストラクタ定義 | abstract シグニチャ定義 | val [mutable] 値、メンバのシグニチャ コンストラクタ定義 := | new パターン [as 識別子] = コンストラクタ式 コンストラクタ式 := | 文 ';' コンストラクタ式 | コンストラクタ式 then 式 | if 式 then コンストラクタ式 else コンストラクタ式 | let 変数宣言 in コンストラクタ式 | オブジェクトの初期化式 オブジェクトの初期化式 := | '{' [ inherit 式; ] フィールド束縛 '}' | new 型 式