GHC.Genericsの提供する型を見る
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)
直積
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
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でない場合も。
data U1 p
とか、 data V1 p
の p
の意味
この p
がなしで定義するとどうなるか
hsdata V1
data U1 = U1
data (f :+: g) = L1 f | R1 g
data (f :*: g) = f :*: g
ここで定義したデータ型をrepresentationとかと呼ぶ
これらは多相ではないので、 Rep f :: *
と書ける(???????????)
わからん

kindが *
なのはわかる
f
が何なのかわからん
ここで、このようなデータ型を使ってFunctorのinstanceにすることを考える
fmap :: (a -> b) -> Rep f -> Rep f
通常はこんな風にやる
fmap :: (a -> b) -> List a -> List b
つまり、 Rep f :: *
の場合だと、型引数を取れないので、 fmap
を実装できない
だから p
を追加することで
hsdata 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:
の部分、おもろいこと言ってる感じがあるが理解できないので一旦スルー
参考
良い記事
理解しきれてないので、理解が進んでから再読したい