Created
January 30, 2019 09:07
-
-
Save notogawa/c122fc1d75531c4f8db30e6d66832ffc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module WhatIsInstance where | |
data Hoge = Foo | Bar | |
-- 型aが同値関係を持つということを示す型 | |
data ThisIsEq a = ThisIsEq { op :: a -> a -> Bool } | |
-- 型Hogeが同値関係を持つ証拠となる値 | |
hogeIsEq :: ThisIsEq Hoge | |
hogeIsEq = ThisIsEq go where | |
go Foo Foo = True | |
go Bar Bar = True | |
go _ _ = False | |
-- 型Boolが同値関係を持つ証拠となる値 | |
boolIsEq :: ThisIsEq Bool | |
boolIsEq = ThisIsEq go where | |
go True True = True | |
go False False = True | |
go _ _ = False | |
-- 任意の型aに対して,"型aが同値関係を持つ" ならば "同値比較が利用できる" | |
equal :: ThisIsEq a -> a -> a -> Bool | |
equal eq a b = op eq a b | |
-- "同値関係を持つという証拠" を "渡し分ける" ことでequalはHogeにもBoolにも対応する | |
testHogeIsEq = equal hogeIsEq Foo Bar | |
testBoolIsEq = equal boolIsEq True True | |
-- しかし,証拠を型によって渡し分けるなんてメンドクサイなぁ | |
-- equalの型宣言にある a -> a -> Bool の部分から, | |
-- 勝手に hogeIsEq 使うとか boolIsEq 使うとか"渡し分ける"のを | |
-- 処理系がやってくれないかなぁ | |
-- | |
-- \ | | | | | | | | | | / | |
-- これが > 型クラスとインスタンス < | |
-- / | | | | | | | | | | \ | |
-- | |
-- まず,型クラスを導入する(ThisIsEq に対応) | |
class HasEq a where | |
equal' :: a -> a -> Bool | |
-- Hogeに対してインスタンスを定義する(hogeIsEqに対応) | |
instance HasEq Hoge where | |
equal' Foo Foo = True | |
equal' Bar Bar = True | |
equal' _ _ = False | |
-- Boolに対してインスタンスを定義する(boolIsEqに対応) | |
instance HasEq Bool where | |
equal' True True = True | |
equal' False False = True | |
equal' _ _ = False | |
-- equal' の型は, HasEq a => a -> a -> Bool となり, | |
-- 元の equal の ThisIsEq a -> a -> a -> Bool と対応 | |
-- aの型から適切なHasEq a (元ThisIsEq a) のインスタンスが選択され, | |
-- "渡し分け"を陽に行わずに同値比較が利用できるようになった | |
testHogeIsEq' = equal' Foo Bar -- 暗黙にHasEq Hoge (元 hogeIsEq)が選択されている | |
testBoolIsEq' = equal' True True -- 暗黙にHasEq Bool (元 boolIsEq)が選択されている | |
-- やったぜ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment