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

Haskellのお勉強 その18

型クラスとは

型クラスとは、型変数の多相型に制限を加えるために使われるクラスのことである。


たとえばリストをソートするsort関数の型宣言をしたいような場合、型変数aを使って

sort :: [a] -> [a]

と書きたいはず。なぜなら、aが整数のリストであっても浮動小数点のリストであっても、
文字列のリストの場合でも、大小の区別がつくような型の値なら何でもソートしたいですから。
でも、中には大小の区別がつかないような値もある。たとえば関数。
関数のリスト[length, head, last]があったとしても、関数に大小なんてないから、これをソートすることはできない。
なので、先ほどのsort関数の型宣言で、「型変数aは大小の区別がつく型に限定する」
ということを指定することができれば、安心できそうだ。その場合は次のように書く

sort :: (Ord a) => [a] -> [a]

ここで出てきた「Ord」が型クラス。型クラスは、単にクラスということもある。
このときOrdクラスは、型aに対して「型に属する値が順序付けできること」という制約を課している。
つまり、「(Ord a) =>」という構文は、「aはOrdクラスの制約を満たす型である」という宣言をしている。
また、型aがOrdクラスの制約を満たすとき、「型aはOrdクラスのインスタンスである」と言う。
C#JavaRubyなどのオブジェクト指向言語インスタンスというと、
「あるクラスから生成したオブジェクト」という意味となるが、
Haskellの場合は、「ある型クラスの制約を満たす型」を意味する。


もう一つ例を見てみる。

elem :: (Eq a) => a -> [a] -> Bool

上記は、「型に属する値の間で値が同じであるかどうかを判断できる」という制約を表す
「Eqクラス」を使って、「型aはEqクラスのインスタンスでなければならない」という宣言をしている。
このように、型クラスによって制約がついた多相性のことを「アドホック多相」と言い、
それに対して、制約のない型変数のような多相性のことを「パラメータ多相」と言う。


注意すべきは、Haskellの型クラスは、型のクラスであって型ではないこと。
値を書くべきところに型を書いてはいけないのと同じように、
型を書くべきところに型クラスを書くことはできない。当たり前っちゃー当たり前だけど。