Haskell: type と typeclass を作る (4)
前回の続き.
Learn You a Haskell for Great Good! の Chapter 8, Making Our Own Types and Typeclasses を元にしたものです.基本的には翻訳のつもりですが,省略や加筆が勝手に入ることもあります.原文は CC-BY-NC-SA でライセンスされており,この文書もそれに従います.
今回は Derived instances から.
Derived instances
以前 に (訳してないけど) typeclass の基本についてはやった.
Typeclass は何らかの挙動を規定する interface のようなもの,という話でしたね.
例えば Int
が Eq
typeclass の instance で,それは Eq
が等値かどうかを判断できるものについて behaviour を定義するものだから,というわけ.
便利さは Eq
の interface として働く函数,つまるところ ==
と /=
とともにもたらされる.
ある型が Eq
typeclass の中にあるなら ==
とか を使えて,こうして 4 == 4
とか "foo" /= "bar"
が型検査を通る.
もうひとつ書いてあったのは,Python や Java, C++ などの class とはずいぶん違うもので,haskell では typeclass から data を作ったりはしない.まず data type を作って,それからそれがどのように振る舞えるかを考えるという流れになる.
ははあ等値性を比べられるな,と思ったら Eq
typeclass の instance にするし,順序の入るものであれば Ord
typeclass の instance にするわけだ.
Typeclass によって定義される函数を実装して type を typeclass の instance にするのはどーするの,ってのは後でやるとして,とりあえず haskell が勝手にやってくれるのを見てみよう.
deriving
を使えば,Eq
, Ord
, Enum
, Bounded
, Show
, Read
あたりはよしなにやってくれます.
data Person = Person {
firstName :: String,
lastName :: String,
age :: Int
} deriving (Eq)
こうすると (各 field の型が全部 Eq
じゃないといけないが) constructor のそれぞれが合ってるかどうかをチェックしてくれる.
ghci> let mikeD = Person {firstName = "Michael", lastName = "Diamond", age = 43}
ghci> let adRock = Person {firstName = "Adam", lastName = "Horovitz", age = 41}
ghci> let mca = Person {firstName = "Adam", lastName = "Yauch", age = 44}
ghci> mca == adRock
False
ghci> mikeD == adRock
False
ghci> mikeD == mikeD
True
ghci> mikeD == Person {firstName = "Michael", lastName = "Diamond", age = 43}
True
いまや Eq
配下なので Eq a
という constraint のあるやつは使えるようになる. elem
とかもね.
あとは Show
とか Read
とか Read
とかの話が出ておしまい.
このあとは type
で作れる synonym とかの話になるが,typeclasses 102 まで飛ばす予定.