TypeFamiliesの全体観を掴む
Type Familyとは何か?という話はガン無視して、
TypeFamiliesという拡張の概念がどのように構成されているか、の全体観を掴む
ここを掴んでいないと、docsを読んでも「え、いま何の話をしてるの?」になってしまうmrsekut.icon
以下、「Type Family」と呼んだり、「型族」と呼んだりすることがあるが同じものを指すmrsekut.icon
いったん型族の話を忘れて通常の型の定義方法について軽く見る
通常の型の定義の仕方には大雑把に分けると以下の2種類がある
新しい型を作るdataとnewtype
これをデータ型と呼ぶ
既存の型に別名を付けるtype
これを型シノニムと呼ぶ
というのを踏まえて、型族の話に進むと、
上のそれぞれに対して、型族の定義の仕方がある
テータ型の型族版
型シノニムの型族版
さらにこの中に、定義する場所や、拡張性の差異によって2,3の分類がある
こんなmatricsで表現できる
table:構成
Data Family Synonym Family
toplevelにopenに定義 Open Data Type Family Open Type Synonym Family
toplevelにclosedに定義 GADT Closed Type Synonym Family
型クラス内に定義(open) Associated Data Type Family Associated Type Family
これだけ見てもわかりにくいので、以下にいくつか補足する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でほとんど同じ説明をしている箇所があるせい