TypeFamilies
Type Familyを扱うGHC拡張
以下の拡張を含む
MonoLocalBinds
KindSignatures
ExplicitNamespaces
docs
訳: /LugendrePublic/型族
TypeFamiliesの大まかな構成
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
詳細はTypeFamiliesの全体観を掴むに書いた
型族とは
型族とは型の族のこと
TypeFamilyを型レベル関数として見る
簡単な例
Open, Closed, Associatedの使い分け
具体的な使用ケースの例
Haskellにおける型レベルプログラミングの基本(翻訳) - Qiita
長さを持つVector n a型同士を連結する関数append :: Vector n a -> Vector m a -> Vector ??? aをどう定義するか?を考える
率直に考えれば、???の部分はn+mになって欲しいが、それを型でどう表現するか
関連論文
Fun with type functions
Associated Type Synonyms
『Type Checking with Open Type Functions』
関連
TypeFamilyDependencies
multi-parameter type class関連のGHC拡張と使い分け
参考
Freer Effectsが、だいたいわかった: 3. 型シノニム族(TypeFamilies拡張)の解説 - Qiita
open→associated→closedの流れで解説されてて、それぞれの意義がわかりやすい
/haskell-shoen/型族に部分適用できない
#WIP
https://zenn.dev/mod_poppo/books/haskell-type-level-programming/viewer/type-families
/mrsekut-private/型族
https://www.yesodweb.com/book/basics
https://wiki.haskell.org/GHC/Type_families
https://ocharles.org.uk/posts/2014-12-12-type-families.html
https://serokell.io/blog/type-families-haskell
http://amixtureofmusings.com/2016/05/19/associated-types-and-haskell/
https://qiita.com/YoshikuniJujo/items/17853e423c39409d8dfe#%E5%9E%8B%E3%82%B7%E3%83%8E%E3%83%8B%E3%83%A0%E6%97%8F%E3%82%92%E4%BD%BF%E3%81%86
https://qiita.com/YoshikuniJujo/items/b3c442d0387a35bfe860
https://qiita.com/rooooomania/items/c6da1158d676e6fe87e2
https://qiita.com/YoshikuniJujo/items/33ce63d115378da66417#flexibleinstances%E6%8B%A1%E5%BC%B5
https://github.com/shiatsumat/wiwinwlh-jp/wiki/%E5%9E%8B%E6%97%8F#mono-traversable
https://qiita.com/lotz/items/6c038698c8f04f57113a
https://ryota-ka.hatenablog.com/entry/2018/03/10/205817
chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/typefun.pdf
https://typesandkinds.wordpress.com/2015/09/09/what-are-type-families/
https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html#type-families
http://www.kotha.net/ghcguide_ja/7.6.2/type-families.html
https://stackoverflow.com/questions/14195497/data-families-use-cases/14196921#14196921
https://qiita.com/lotz/items/6c038698c8f04f57113a#associated-type-family
https://en.wikipedia.org/wiki/Type_family
https://scrapbox.io/haskell-shoen/Generics
https://www.stephendiehl.com/posts/haskell_2017.html
https://typesandkinds.wordpress.com/2013/04/29/coincident-overlap-in-type-families/
https://www.fpcomplete.com/blog/2017/06/tale-of-two-brackets/
https://cs.stackexchange.com/questions/55475/family-of-types-in-type-theory
chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/https://www.cs.cmu.edu/~rwh/papers/extidx/paper.pdf
https://mizunashi-mana.github.io/blog/posts/2019/11/trees-that-grow/
https://keigoi.hatenadiary.org/entry/20091116/1258358996
#??
openからclosedへの書き換え
ユースケース
依存型とはまた違うのか
Idrisで依存型に触れるやった内容に似てる
アドホック多相と、型クラス、型族のアナロジーを見てたら
ただのパターンマッチとアドホック多相の違いがわからなくなった
例 ref
型族Add
code:hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances, DataKinds #-}
data Nat = Zero | Succ Nat
type family Add n m where
Add 'Zero n = n
Add ('Succ n) m = Add n ('Succ m)
code:ghci
:kind Add
Add :: Nat -> Nat -> Nat
:kind! Add
Add :: Nat -> Nat -> Nat
= Add
:t Add -- error
kind!で正規化した型を表示する
code:prelude
:kind! Add (Succ (Succ Zero)) (Succ Zero) -- 2+1
Add (Succ (Succ Zero)) (Succ Zero) :: Nat
= 'Succ ('Succ ('Succ 'Zero)) -- 3
関数で書いた場合のイメージ
code:hs
add :: Nat -> Nat -> Nat
add Zero n = n
add (Succ n) m = add n (Succ m)
Natはkind
型族If
code:hs
type family If c t f where
If 'True t f = t
If 'False t f = f
:kind!で型関数を実行できる
open, closed, 型クラス内の流れ
openに焦点を当てる
普通にトップレベルで定義できるが、ユースケースを考えると型クラスと一緒に使われがち
だから型クラスで一緒に書いちゃおうと言うのが、型クラス内の定義のやつ
外部から拡張不可能にしたい場合はclosedで定義する
できることがやや増える
つまり、open→closedな書き換えは常に可能だが、逆は無理 #??
openに定義したが型クラスと併用したいパターンってあるのか #??
closedに定義したやつはどういうふうに使われるのか #??
Functional Dependenciesとの関係性
https://github.com/shiatsumat/wiwinwlh-jp/wiki/型族
fun depsは単射性を要請するが、型族はそうでもない
https://www.fpcomplete.com/haskell/tutorial/fundeps/
multi-parameter type classとの関係
パット見似たようなもののように見えるが、どう使い分けるのか?
https://gitlab.haskell.org/ghc/ghc/-/issues/11534
両方使ってるやつおるん??
『Type Checking with Open Type Functions』とかで説明されている
GADTとの関係性
上のマトリックスTypeFamilies#6114b17b1982700000e2eae5の穴
本当に同じものなのかどうかの確認
https://github.com/shiatsumat/wiwinwlh-jp/wiki/型族
wiwinwlhは示唆に富むンゴねえ
mono-traversable
FUnctor, Foldable, Traversableの一般化
https://github.com/shiatsumat/wiwinwlh-jp/wiki/型族#mono-traversable
今から見ようとしている型クラスにtype familyがあったら何を連想できるか?
つまり、今から見ようとしている型クラスがAssociated Type Familyで定義されている場合、何を意味するか
Representableとか
code:hs
class Functor f => Representable f where
type Log f :: *
index :: f a -> (Log f -> a)
tabulate :: (Log f -> a) -> f a
positions :: f (Log f)
tabulate h = fmap h positions
positions = tabulate id
Genricとか
code:hs
class Generic a where
type family Rep a :: * -> * -- representation of the data a
from :: a -> Rep a x
to :: Rep a x -> a
instanceを定義するときに、type familyを指定する必要がある
型関数の返り値となる型を自由に(?)指定できる
それぞれのインスタンス宣言ごとに、区別された 型コンストラクタが作られるイメージ
上ならinstanceごとに別々のLog A _、Log B _といった型コンストラクタができる
要は、multi paramな型クラスである、と考えたほうがわかりやすいかも
2つ以上の型引数を取る型クラスの表現の仕方としてこの表記がある
定義時の型引数はkindが一致していないといけいないのか
code:hs
type family Add n m where
Add 'Zero n = n -- 'ZeroのkindはNat
Add ('Succ n) m = Add n ('Succ m) -- 'SuccのkindはNat
Add String String = Add Int String -- Stringのkindは*なのでエラー
#??
class内にtype宣言する構文も入る
code:hs
class HasKey a where
type Key a
wrapKey :: Int -> Key a
unwrapKey :: Key a -> Int
ここでみた
TypeFamilyDependencies
参考
https://qiita.com/rooooomania/items/c6da1158d676e6fe87e2
https://wiki.haskell.org/GHC/Type_families