Default definitions

2005年1月13日 結城浩

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

[craft] 2005年1月13日 09:29

記事一覧

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 ]

Bloglines

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)

記事検索 サイト検索はこちら

豊かな人生のための四つの法則