ようこそ。睡眠不足なプログラマのチラ裏です。

Haskellのお勉強 その19

クラスメソッド

Eqクラスの制約を満たす型は、「(==)関数で同値検査ができる」
あるいは、「(/=)関数で同値ではないという検査ができる」という制約を満たす。
また、Ordクラスは「(>)関数や(<)関数などの関数で比較できる」という制約を満たす。
これらの関数は、「そのクラスを特徴付ける関数」と考えることができる。
こうした「Eqクラスに対する(==)関数や(/=)関数」「Ordクラスに対する(>)関数や(<)関数」のような
「あるクラスを特徴付ける関数」のことを、「クラスメソッド」と言う。


多重定義

「ある型t」を「ある型クラスc」のインスタンスとして実装したい場合、
「型t」は「型クラスc」のすべてのクラスメソッドが実装されている必要がある。
しかし、クラスメソッドは、型によって実装のしかたが異なりそうだ。
たとえば同じ「等しい」でも、「単なる値だけの型」と「構造を持った型」では
「等しい」を判断するための関数の実装方法が異なるだろう。


Haskellでは、型ごとにクラスメソッドの実装方法を変えることができる。
これを、「クラスメソッドの多重定義」と呼ぶ。


型クラスの継承

Ordクラスのクラスメソッドには、「(<=)関数」や「(>=)関数」のように、
「等しさ」の判断も必要とされる関数も含まれている。
この2つのクラスメソッドを実装するにはEqクラスのクラスメソッド「(==)関数」もあったほうが良いだろう。
つまり「Ordクラスのインスタンスは、常にEqクラスのインスタンスでもある」という条件があると便利っぽい。
Haskellでは、このような条件を「型クラスの継承」として表現することができる(class宣言)。
型クラスを継承すると、継承元の型クラスのクラスメソッドがあることを前提にして
クラスメソッドを実装することができる。例えば、Ordクラスを定義する場合、
Eqクラスを継承していれば、Ordクラスのクラスメソッド(>=)関数や(<=)関数を実装するときに、
(==)関数を利用することができるようになる。


また、「OrdクラスがEqクラスを継承している」という関係のとき、
「EqクラスはOrdクラスのスーパークラスである」と表現し、
またその逆に、「OrdクラスはEqクラスのサブクラス」という表現をする。
これは普通のプログラマにとっては、お馴染みの表現ですな。