TypeFamiliesの全体観を掴む
Type Familyとは何か?という話はガン無視して、
ここを掴んでいないと、docsを読んでも「え、いま何の話をしてるの?」になってしまうmrsekut.icon
以下、「Type Family」と呼んだり、「型族」と呼んだりすることがあるが同じものを指すmrsekut.icon
いったん型族の話を忘れて通常の型の定義方法について軽く見る
通常の型の定義の仕方には大雑把に分けると以下の2種類がある
新しい型を作るdataとnewtype
これをデータ型と呼ぶ
既存の型に別名を付けるtype
これを型シノニムと呼ぶ
というのを踏まえて、型族の話に進むと、
上のそれぞれに対して、型族の定義の仕方がある
テータ型の型族版
型シノニムの型族版
さらにこの中に、定義する場所や、拡張性の差異によって2,3の分類がある
こんなmatricsで表現できる
table:構成
これだけ見てもわかりにくいので、以下にいくつか補足するmrsekut.icon
列ごとに見れば、データ型、型シノニムで分かれている
行ごとに見た場合、2つの分け方がある
型クラス内に定義されているか、toplevelに定義されているか
拡張に対してopenであるか、closedであるか
データ型のclosedな定義は、TypeFamiliesでは提供されていない
別の拡張(GATD)で同様のことができる
型クラスの定義時に、class宣言とinstance宣言が必要なように、
それぞれのパターンに対し、型族宣言とinstance宣言がある
closedなものは型族宣言とinstance宣言をセットで同じ場所に書くが、
openなものはバラバラな場所に書くことができる
それが「open」の意味mrsekut.icon
例えば、Libraryが型族宣言を提供して、利用者がそのinstanceを好きに定義できる
closedな場合はそのようなことはできない
実際の利用時のイメージとしては、「型クラス内に定義」は「toplevelにopen」の特殊版という感じ
「toplevelにopen」でも良いが、結局、型クラスと一緒に使うことが多いので、
「型クラス内に定義しちゃおうや」というイメージ
toplevelというのは普通に型を定義するときと同様に、
file内の0個のnestな場所で定義することを言っている
code:hs
-- toplevel
type A = Int
class A where
-- toplevelではない
type A = Int
初見でdocsが分かりづらい理由
単語が微妙に揺れている
「indexed」が付いてたり付いていなかったりする
「○○はn種類ある」というのを各節で言っているのでわかりづらい
最初に全体の話をするともっとわかりやすくなるのにmrsekut.icon
Indexed type families come in three flavours: data families, open type synonym families, and closed type synonym families.
ここでは、データ族、open, closedの3つで括っている
上のmatricsで言えばこう分けている
https://gyazo.com/e5057ca0786deea34c087210e35ea2a6
間違ってはないが、分かりづらい括り方をしている
全体の構造がわかっていれば、何の話してる?とならんので理解できる
最初、上から読んでいって、あれこの話さっきも出てきたな?となった
dataとtypeでほとんど同じ説明をしている箇所があるせい