7. 型とは?
一旦、オブジェクト指向のクラスを忘れて、型について思い出しましょう。
※ 用語: 型 と データ型 は同意
int i = 123;
char c = 'a';
C言語
Java
int i = 123;
boolean b = true;
// String s = "abc" // String is Class, not data type.
Haskell
Prelude> :t True
True :: Bool
赤枠が"型"です。※クラスではありません。
12. 「型クラスのインスタンスである型」とは?
Prelude> 123 == 123
True
Prelude> 'a' == 'b'
False
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Eq は型クラスです。
a は型です。
Eq a => はa型はEq型クラスのインスタンスである必要がある制約です。
(==)関数は、引数にEq型クラスのインスタンスa型を2つとり、Bool型を返し
ます。
Javaのinterfaceに似てるかも?
Haskell
13. 「型クラスのインスタンスである型」とは?
Prelude> :i Int
data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in ‘GHC.Types’
..
instance Eq Int -- Defined in ‘GHC.Classes’
..
Prelude> :i Char
data Char = GHC.Types.C# GHC.Prim.Char# -- Defined in ‘GHC.Types’
..
instance Eq Char -- Defined in ‘GHC.Classes’
..
Int型も、Char型も、Eq型クラスのインスタンスで
す。
14. 「型クラスはインターフェースを定義してる」とは?
Prelude> :i Eq
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not(x/=y)
x /= y = not(x==y)
== 関数 と /= 関数が実装すべき関数(インターフェース)です。
※ Eq型クラスはデフォルト実装が定義されているので、 (==)
を実装すれば最小完全定義を満たせる
15. 「型クラスはインターフェースを定義してる」とは?
Prelude> :i TrafficLight
data TrafficLight = Red | Yellow | Green
Prelude> Red == Red
No instance for (Eq TrafficLight) arising from a use of ‘==’
Prelude> :set +m
Prelude> instance Eq TrafficLight where
Prelude| Red == Red = True
Prelude| Green == Green = True
Prelude| Yellow == Yellow = True
Prelude| _ == _ = False
Prelude|
Prelude> :i TrafficLight
data TrafficLight = Red | Yellow | Green
instance Eq TrafficLight
Prelude> Red == Red
True
自分で定義した型をEq型クラスのインスタンスにしてみる
↑この時点では (==) は使えない
←Eq型クラスのインスタンスにしたので
(==) が使えるようになった!