5. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
リスト
.
リスト型
.
. data List a = Empty | Cons a (List a)
レコード構文で書くと
data List a = Empty | Cons { listHead :: a
, listTail :: List a
}
Empty は []
Cons x xs は x : xs に対応する
6. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
リストの改善
.
リスト型’
.
infixr 5 : -:
. data List a = Empty | a : -: (List a)
記号文字だけで値コンストラクタに出来る
名前はコロン : から始めないといけない
:: は使えない
コロン : から始まる二項演算子は定義できない
× x : + y = x + y,⃝ x + : y = x + y
コロンは大文字として考える (@nushio さん)
infix, infixl, infixr で結合性を定めることが出来る
デフォルトは infixl 9
例) infixl 7 ∗, infixl 6 +,infixl 6 ‘xor‘,infixr 5 ‘Cons‘
7. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
リストの改善
.
(++)
.
infixr 5 ˆ++
(ˆ++) :: List a → List a → List a
Empty ˆ++ ys = ys
. (x : -: xs) ˆ++ ys = x : -: (xs ˆ++ ys)
パターンマッチも使える!!
9. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
二分探索木
.
二分探索木データ型
.
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
.
簡単のため平衡木にはしません
挿入,探索をする
treeInsert :: a → Tree a → Tree a
treeElem :: a → Tree a → Bool
を実装していきます
11. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
クラス
.
Eq 型クラス
.
class Eq a where
(==), (/ =) :: a → a → Bool
x == y = not (x / = y)
x/= y = not (x == y)
.
補足
Eq は等値性を表すクラスですが,
EQ は Ordering 型の値です.
data Ordering = LT | EQ | GT
12. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
インスタンス宣言
.
交通信号データ型を Eq のインスタンスに
.
data TrafficLight = Red | Yellow | Green
instance Eq TrafficLight where
Red == Red = True
Yellow == Yellow = True
Green == Green = True
== = False
.
(/ =) まで定義しなくて良い =⇒ 最小完全定義
13. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
インスタンス宣言
.
Show のインスタンスに
.
instance Show TrafficLight where
show Red = “Red light”
show Yellow = “Yellow light”
show Green = “Green light”
.
14. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
サブクラス化
.
Num クラス
.
class (Eq a) ⇒ Num a where (以下省略)
.
Num は Eq のサブクラス
Eq は Num のスーパークラス
Num のインスタンスに出来るのは Eq クラスのもの
だけ
a を Num のインスタンスにしようと思うと Eq のイ
ンスタンスにしないといけない
(ちなみに GHC 7.4.1 で Eq を Num のスーパークラス
にするという制約は取り除かれました.)
15. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
多相型を型クラスのインスタンスに
.
問題
.
Maybe を Eq のインスタンスにするにはどうすればい
いか?
.
class Eq a where
(==), (/ =) :: a → a → Bool
x == y = not (x / = y)
x/= y = not (x == y)
Maybe は具体型ではないので,
instance Eq Maybe where と出来ない.
16. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
多相型を型クラスのインスタンスに
.
Maybe を Eq のインスタンスに
.
instance Eq (Maybe a) where
Just x == Just y = x == y
Nothing == Nothing = True
. /= = False
Maybe は具体型ではないが,Maybe a は具体型.
しかし,まだ1つ問題が残っています.
a が Eq のインスタンスになっていないと x == y が使え
ない.
17. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
多相型を型クラスのインスタンスに
.
Maybe を Eq のインスタンスに (完成版)
.
instance (Eq a) ⇒ Eq (Maybe a) where
Just x == Just y = x == y
Nothing == Nothing = True
. /= = False
19. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
YesNo 型クラス
.
YesNo 型クラス
.
class YesNo a where
. yesno :: a → Bool
Int, [a], Bool, Maybe a, Tree a, TrafficLight
を YesNo のインスタンスにします.
YesNo 用の ifっぽい関数 yesnoIf
20. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
Functor(関手)型クラス
.
Functor 型クラス
.
class Functor f where
. fmap :: (a → b) → f a → f b
map :: (a → b) → [a] → [b] に似てるなぁ
f a が具体型なので,f は型引数を 1 つもつ型コンスト
ラクタ(クラスに出来るのは具体型だけではない)
fmap は Functor 則を満たさないといけない
fmap id = id
fmap f . fmap g = fmap (f . g)
詳細は 11 章
21. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
リスト Functor
.
リストを Functor に
.
instance Functor [] where
fmap = map
.
instance Functor [a] where ではない
[] は空リストではなくて [] a の []
fmap :: (a → b) → [] a → [] b
22. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
Maybe Functor
.
Maybe を Functor に
.
instance Functor Maybe where
fmap Nothing = Nothing
. fmap f (Just a) = Just (f a)
instance Functor (Maybe a) where ではない
fmap :: (a → b) → Maybe a → Maybe b
左の Nothing は Maybe a 型
右の Nothing は Maybe b 型
fmap f (Just a) = Just (f a)
fmap x = x
は型エラー
23. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
Tree Functor
.
Tree を Functor に
.
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
instance Functor Tree where
fmap EmptyTree = EmptyTree
fmap f (Node x left right)
. = Node (f x) (fmap f left) (fmap f right)
25. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
Either Functor
.
Either を Functor に
.
instance Functor (Either a) where
fmap (Left x) = Left x
. fmap f (Right y) = Right (f y)
型引数が複数ある時は部分適用させる
fmap :: (b → c) → Either a b → Either a c
よく使う方を Right にした方がよさそうですよね
26. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
読者への練習問題
.
問題
.
Data.Map も Functor にできます.どのように Functor の
インスタンスになるでしょうか?
.
とりあえず,fmap の型は. ..
fmap :: (a → b) → Map k a → Map k b
Hoogle にきいてみると.
..
28. 7.7 再帰的なデータ構造 7.8 型クラス 中級講座 7.9 Yes と No の型クラス 7.10 Functor 型クラス 7.11 型を司るもの、種類
...... ........ .. ....... ..
演習
Functor クラスのインスタンスにして下さい.
data Akari a = Waai a (Akari a) | Daisuki
data H oo gle = H oo oo oo oo oo gle
data Ha y oo = Ha y oo oo oo oo oo
data O b = OOOO|OOOOOO|O|OO
data Hom r a = Hom (r → a)
data State s a = State (s → (a, s))
data Just a = Nothing | Maybe (Maybe a)
ヒント
作るのは map 関数みたいなもの
とりあえず型を合わせる
fmap id が id になるように (Functor 則の1つ)