generated at
GHC.Genericsの提供する型を見る
Genericで生成された型を見ると併せて見るとわかりやすい




data V1 p
型の数が0のもの


data U1 p = U1
型の数が1のもの


data (:+:) f g p = L1 (f p) | R1 (g p)
直和


data (:*:) f g p = (f p) :*: (g p)
直積


newtype K1 i c p = K1 { unK1 :: c }
値コンストラクタの引数に当たる型を表す
第1引数は R はRuecursiveを表すと書いてるが、どの辺が再帰なのかわからない #??
e.g. K1 R Int , K1 R Bool
K1 P というのもあったがdeprecated




newtype M1 i t f p = M1 { unM1 :: f p }
i は、 D , C , S のいずれかを取る
D : Datatype
C : Constructor
S : Record Selector #??
t には、メタ情報が含まれる
i ごとに別の値をを取る
D とのとき
例えば ('MetaData "Hoge" "Fuga.Hoge" "main" 'False) は、それぞれ
型名、module名、(mainは知らん)、newtypeかどうかを表す
newtypeならTrue, dataならFalseになる
C のとき
例えば ('MetaCons "H2" 'PrefixI 'False) は、それぞれ
コンストラクタ名、fixity、レコードかどうかを表す
仮に data I a = I a :&: a みたいな型を定義すれば、 InfixI になる
仮に data R = R { a :: String } みたいな型を定義すれば、最後はTrueになる
S のとき
Selector名が示される
Record Selectorでない場合も。
Selectorってなに #??



data U1 p とか、 data V1 p p の意味
この p がなしで定義するとどうなるか
hs
data V1 data U1 = U1 data (f :+: g) = L1 f | R1 g data (f :*: g) = f :*: g
ここで定義したデータ型をrepresentationとかと呼ぶ
これらは多相ではないので、 Rep f :: * と書ける(???????????)
わからんmrsekut
kindが * なのはわかる
f が何なのかわからん
ここで、このようなデータ型を使ってFunctorのinstanceにすることを考える
fmap :: (a -> b) -> Rep f -> Rep f
通常はこんな風にやる
fmap :: (a -> b) -> List a -> List b
つまり、 Rep f :: * の場合だと、型引数を取れないので、 fmap を実装できない
だから p を追加することで
hs
data V1 p data U1 p = U1 data (f :+: g) p = L1 (f p) | R1 (g p) data (f :*: g) p = (f p) :*: (g p)
fmap :: (a -> b) -> Rep f a -> Rep f b とできる
But what happens to the type classes that work with * kinds? Our choices are:
の部分、おもろいこと言ってる感じがあるが理解できないので一旦スルー




参考
良い記事
理解しきれてないので、理解が進んでから再読したい