Haskellの型システムについて
Haskellでは2種類のpolymorphismがサポートされている。それはParametric PolymorphismとAd-hoc Polymorphismである。
- Parametric Polymorphism
型に関わらず同じ操作を行う場合に発生するpolymorphism。例えばソートアルゴリズム等は要素の比較や同一性判定に使用する部分を除いては、要素の型に依存しないのでparametric polymorphismを持つ。例えばC++のテンプレート。
- Ad-hoc Polymorphism
型の種類に依存して、行われる操作が異なる場合に発生するpolymorphism。例えばC言語における+演算子はint, floatの両方の型に適応できるが、内部で使用されているアルゴリズムは全く異なる。
以上2つのpolymorphismの概念を理解した上で、Haskellのclass, instanceキーワードをみていく。
- Parametric Polymorphism
例えばlength関数。
length :: [a] ~> Integer length [] = 0 length (x:xs) = 1 + length xs
この関数は、リストの中身の型がどのような型で有っても適応可能である。
length [1, 2, 3] => 3 length ['a', 'b', 'c'] => 3 length [[1], [2], [3]] => 3
- Ad-hoc Polymorphism
JavaやC++ではclass定義にメンバ変数等のデータ構造の定義と関数の定義の両方を記述するが、Haskellではそれが分離されており、class定義にはそのclassに属する関数(method)だけを定義する。Javaのインターフェースに相当すると言って良いかも。
class Eq a where (==) :: a -> a -> Bool
instanceを使用して、Eqで定義されている== methodを再定義する。
instance Eq Integer where x == y = x `integerEq` y
これでInteger型に== methodを追加する事が出来る。
-
-
- -
-
Haskellには他にも型に関連するものとしてdata, typeというキーワードが有る。
- data
dataは以下のようにして用い、1つまたはそれ以上のdata constructorを定義する。
data Bool = False | True data Point a = Pt a a
Boolの様に複数のdata constructorが有る型を(disjoint) unionやsum typesと呼ぶ。逆に一つのdata constructorしか持たないPointのような型をtuple typeと呼ぶ。
Pointの所を見ると、ここにもPolymorphismが登場している。例えばPt data constructorを使用して以下の様にデータを構築できる。
Pt 2.0 3.0 Pt 'a' 'a' Pt True False
Pt :: a -> a -> Point aである為に、内容の型には無関係となる。
- type
typeは既にある型に対して別名を付けるためのキーワードだ。
type String = [Char] type Person = (Name, Address) type Name = String data Address = None | Addr String
Polymorphicな型の別名を付ける事もできる。
type AssocList a b = [(a, b)]