| ホーム > Haskell > 2005年1月13日 > Default definitions | 記事の検索 | サイト検索 | 更新情報 |
| プロフィール | 記事一覧 | リンク集 | RSS |
|
CRAFT 12.3を読んでいる。
(==)と(/=)の定義が以下のようになっているのを見て、最初は驚いた。
class Eq a where
(==) :: a -> a -> Bool
x == y = not (x /= y)
(/=) :: a -> a -> Bool
x /= y = not (x == y)
無限ループになってしまうような気がしたからだ。 でも、そうではなく、 Eqのinstanceが、(==)と(/=)のどちらか一方でも定義すればよいということになる。
Javaでメソッドのoverrideというと、スーパークラスのメソッドをoverrideすることを意味するが、 Haskellではclassの演算子をinstanceがoverrideするらしい。
練習してみよう。
module Main where
data Color = Red | Pink | Green | Grass | Blue | Skyblue
instance Eq Color where
Red == Pink = True
Green == Grass = True
Blue == Skyblue = True
_ == _ = False
t1 = Red == Pink
t2 = Red /= Pink
t3 = Green == Skyblue
t4 = Green /= Skyblue
Main> t1 True Main> t2 False Main> t3 False Main> t4 True
ここでは、Colorというtypeに対して演算子(==)だけを定義している。 しかしちゃんと、(==)と(/=)が使えるようになっている。
ちなみに、ColorというtypeはEqというclassのinstanceである。 Javaのclassはtypeとほぼ同義だが、Haskellのclassはtypeの集まりである。 用語が微妙に違うので注意が必要である。
ところで、もしも(==)と(/=)の両方を定義しなかったらどうなるだろう。 以下のように、スタックオーバーフローを起こす。
module Main where data Color = Red | Pink | Green | Grass | Blue | Skyblue instance Eq Color t = Red == Pink
Main> t ERROR - C stack overflow
2006 [ 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 ]
2005 [ 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 ]
2004 [ 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 ]
book(3) / char(2) / compiler(3) / craft(5) / data(7) / enum(1) / geb(2) / hawiki(1) / hugs(1) / info(1) / io(3) / list(2) / map(3) / monad(16) / nobsun(12) / report(4) / sicp(2) / soe(8) / suchthat(2) / yaht(8)