Hackageを検索したところ、次のようなものは見つかりませんでしたが、それはかなりシンプルで便利です。ある種のデータ型を含むライブラリはありますか?制約のある異種リスト
data HList c where
(:-) :: c a => a -> HList c
Nil :: HList c
私が見つけたすべてのHListは、任意のタイプを持つことができ、制約されませんでした。
私は自分自身をアップロードします。
Hackageを検索したところ、次のようなものは見つかりませんでしたが、それはかなりシンプルで便利です。ある種のデータ型を含むライブラリはありますか?制約のある異種リスト
data HList c where
(:-) :: c a => a -> HList c
Nil :: HList c
私が見つけたすべてのHListは、任意のタイプを持つことができ、制約されませんでした。
私は自分自身をアップロードします。
私はこのデータ型が有用であるかわからない...
あなたは本当にa
は実存資格になりたい場合は、私はあなたが定期的にリストを使用すべきだと思います。あなたのHList c
が[Exists c]
に同型であり、あなたがまだのすべてを使用することができ、その後
data Exists c where
Exists :: c a => a -> Exists c
:ここより興味深いデータ型は、私は確信しているが、それはすべての変異体はすでにパッケージ Hackageの上にあり、Exists
だろう通常のリストベースの関数です。一方
あなたは必ずしも(:-) :: c a => a -> HList c
でa
は(HList
のポイントを挑発するように一種としてそれを持つ)実存的修飾にしたくない場合は、あなたの代わりに、以下を定義する必要があります。
HList
のすべてのエントリがc
を満たすことを要求する場合data HList (as :: [*]) where
(:-) :: a -> HList as -> HList (a ': as)
Nil :: HList '[]
その後、あなたは、そのインスタンス解像度HList
のすべての種類の制約を満たしている場合にのみ機能します[Exists c]
にHList as
からの注入を目撃するタイプのクラスを作ることができます。
class ForallC as c where
asList :: HList as -> [Exists c]
instance ForallC '[] c where
asList Nil = []
instance (c a, ForallC as c) => ForallC (a ': as) c where
asList (x :- xs) = Exists x : asList xs
関連する質問はどこにでも存在していますか?私は基本的に "存在"である "polydata"をアップロードしましたが、重複を保存するためにすでに存在していれば誰かのパッケージも同様ですhttps://hackage.haskell.org/package/polydata-0.1.0.0/docs/Data -Poly.html – Clinton
これは古くなっていますが、その周辺を検索すると['exists']というパッケージが表示されます(http://hackage.haskell.org/package/exists-0.2/docs/Data-Exists.html)... – Alec
ありがとうございます、ExistsとPolyは違います。 – Clinton
generics-sop
パッケージは、箱から出して、これを提供しています。
異種リストは
data NP :: (k -> *) -> [k] -> * where
Nil :: NP f '[]
(:*) :: f x -> NP f xs -> NP f (x ': xs)
を使用し、(Data.Functor.Identity
から)同一タイプ(generics-sop
から)コンストラクタI
又はIdentity
にそれをインスタンス化することによってgenerics-sop
に定義することができます。
この場合、ライブラリは制約All
を提供します。
All Show xs => NP I xs
はすべて含まれているタイプがShow
クラスである異種リストのタイプです。概念的には、All
はタイプレベルのリスト内のすべての要素についての制約を計算タイプの家族である:
type family All (f :: k -> Constraint) (xs :: [k]) :: Constraint where
All c '[] =()
All c (x ': xs) = (c x, All c xs)
(それは部分的にできるように実際の定義では、All
を追加型クラスに包まれているだけということ適用されます)。
さらにライブラリには、共通の制約がある場合、NP
を走査して変換するあらゆる種類の関数が用意されています。
何が本当にしたいことは
あなたはどちらか通常の異質リストtype HList = HKList Identity
または一部の各値に添付定数型e
(または他の興味深いの追加情報と同様に使用することができます
data HKList :: (k -> *) -> [k] -> * where
Nil :: HKList f '[]
(:*) :: f x -> HKList f xs -> HKList f (x ': xs)
ですファンクタ)
HKList ((,) e)
または追加情報辞書
data Has c a where
Has :: c a => a -> Has c a
type ConstrainedList c = HKList (Has c)
でキャプチャそれとも、制約
class All c xs where
dicts :: HKList (Dict1 c) xs
instance All c '[] where
dicts = Nil
instance (All c xs, c x) => All c (x ': xs) where
dicts = Dict1 :* dicts
満たすタイプのリストのすべてのアイデアを定義するために使用できる唯一の捕獲制約
data Dict1 :: (k -> Constraint) -> k -> * where
Dict1 :: c k => Dict1 c k
のリストを維持する上で
または種類でできることその他のものk -> *
あなたは自由にすることができますエリーAll c xs => HList xs
とHKList (Has c) xs
zipHKList :: (forall k. f k -> g k -> h k) -> HKList f xs -> HKList g xs -> HKList h xs
zipHKList _ Nil Nil = Nil
zipHKList f (x :* xs) (y :* ys) = f x y :* zipHKList f xs ys
allToHas :: All c xs => HKList Identity xs -> HKList (Has c) xs
allToHas xs = zipHKList f dicts xs
where
f :: Dict1 c k -> Identity k -> Has c k
f Dict1 (Identity x) = Has x
hasToAll :: HKList (Has c) xs -> Dict (All c xs)
hasToAll Nil = Dict
hasToAll (Has x :* xs) =
case hasToAll xs of
Dict -> Dict
での作業の間の変換私は、様々なプロジェクトのために数回前にこれを書いたが、私はそれがどこかKosmikus pointed out that it's in generics-sop
までライブラリに知りませんでした。
他の答えで説明したように、 'All 'をタイプファミリーに変えて明示的に' dicts'を計算するのではなく、直接使用する方がやや良いと思います。この目的のために、 'generics-sop'は' zipHKList'のような要素の上に 'All'制約を使用して配布することができるような関数の"制約付き "バージョンを提供します。 – kosmikus
どちらも見たことがありません。私は少し前のようなことに取り組んだことがありますが、アップロードする必要があると感じたフォームではそれを持っていませんでした。 [また、タイプシステムのいくつかの奇妙なコーナーにこれを探ることができます](https://github.com/roboguy13/existentialist/blob/master/src/Data/Existentialist.hs#L67)。 –