最初に定義の一部がありません:data family
宣言自体。
data family HList (l :: [*])
data instance HList '[] = HNil
newtype instance HList (x ': xs) = HCons1 (x, HList xs)
これはdata family
(TypeFamilies
拡張の下で入手可能)と呼ばれています。
pattern HCons x xs = HCons1 (x, xs)
これは双方向パターンです(PatternSynonyms
拡張子で入手可能)。
私が見ている'[]
と(x ': xs)
の構文は何ですか?
'
のマークがコンストラクタの前に表示されている場合は、promoted type-level counterpartsとなります。構文の便宜上、このすべてがDataKinds
拡張を介して利用可能である。promoted lists and tuplesまた、単に余分なダニを必要とする(と我々はまだ空のタイプレベルのリストとタイプレベルの短所について':
ため'[]
を書くことを得る。
はい、それはHList
は具象的roleを持っていることを確認することですHCons1
?
のボクシングを避ける以外に(代わりに、2つのフィールドを持つデータ宣言の)タプルとnewtype
宣言を使用して任意のポイントは、どのありあなたが元気にできることを意味します(HList
s )の間にある。これはちょうど答えで説明するの少しも関与しているが、ここでは代わりにnewtype instance
(無パターン)の
data instance HList (x ': xs) = HCons x (HList xs)
を持っているとき、私たちが望むようなものが行かないところの一例です。次newtype
representationally Int
と同等であり、S、Bool
、および()
それぞれ
newtype MyInt = MyInt Int
newtype MyBool = MyBool Bool
newtype MyUnit = MyUnit()
我々は自動的にこれらの型をラップまたはアンラップするcoerce
を使用することができますリコールを考えてみましょう。さて、私たちは同じことを行うことができるようにしたいが、全体HList
ためだろう:
ghci> l = (HCons 3 (HCons True (HCons() HNil))) :: HList '[Int, Bool, ()]
ghci> l' = coerce l :: HList '[MyInt, MyBool, MyUnit]
これはnewtype instance
バリアントで動作しますが、理由は役割のないdata instance
1。 (そのhereの詳細。)
技術的に
は、全体としてdata family
ためのロールが存在しない場合:役割は、各instance
/newtype
ごとに異なることができます - ここで私たちはだけは本当ににHCons
ケースを必要とします表現力があれば、それは強制的になるからです。 Check out this Trac ticket。
'(l :: [*])'は種類パラメータ 'l'が種別' [*] 'に制限されていることを意味しますか? – Textfield
@Textfieldまさに!持っている型パラメータは、型の宣伝されたリストです。それを考えてみると、コンパイルすると 'KindSignatures'もオンにし、おそらく' Data.Kind'もインポートする必要があるかもしれません... GHCがあなたにアドバイスするものは何でもしてください。 :) – Alec