このタイトルは、あまり説明的ではありませんが、短いタイトルでこれをどのように記述するかわかりません。私はどんな勧告にも感謝しています!一般的なtypeclassインスタンスを一連の小さなインスタンスから推論しますか?
私は私の問題の非常に単純化されたバージョンを提示するつもりです:)
だから私は与えられたの正規の建設を生成することができるようになっている型クラス
class Known f a where
known :: f a
を持っています特定のインデックスに入力すると、GADTなどで作業するのに便利です。私はthisの簡略化されたバージョンを提供しています。
instance Known Proxy a where
known = Proxy
我々が使用することができます:
だから、明らかにProxy
のインスタンスがあります
> known :: Proxy Monad
Proxy
をしかしthis HList-like typeのインスタンスもあります:
data Prod f :: [k] -> * where
PNil :: Prod f '[]
(:<) :: f a -> Prod f as -> Prod f (a ': as)
infixr 5 (:<)
はどこProd f '[a,b,c]
はなりおおよそに相当するタプル。同じFunctor、異なるタイプ。インスタンスを書く
はちゃんと簡単です:
> known :: Prod Proxy '[1,2,3]
Proxy :< Proxy :< Proxy :< PNil
しかし、私は私が作る必要がある場合にはよ(表示するインスタンスを想定):かなりうまく動作します
instance Known (Prod f) '[] where
known = PNil
instance (Known f a, Known (Prod f) as) => Known (Prod f) (a ': as) where
known = known :< known
すべてas
に "多型"関数がありますが、GHCはそれを好きではありません。
asProds :: forall as. Proxy as -> Prod Proxy as
asProds _ = known :: Prod Proxy as
それは、このエラーを思い付く:
私は、GHCはそれはそれは 任意のas
のために動作します選択されますインスタンスが存在することを示すことができないと言っていると思います
No instance for (Known (Prod f) as)
arising from a use of 'known'
または、そのインスタンスに対してknown
を構築する戦略がありません。
私は人間として、これが当てはまることを知っていますが、これを動作させる方法はありますか?インスタンスはすべて「範囲内」で利用可能ですが、どのようにGHCに満足する方法でそれを構築するかを教えてもらえますか?
Ah。残念なことに、このような制約を回避することが、私が最初にこれを実行する理由です。しかし!私の問題は、当初、私の存在のすべてに対して '(Applicative(Foo ns)、Foldable(Foo ns)) 'などを指定する必要があり、これですべてを取り除くことができると思ったのです。しかし、今私は、これらのさまざまな制約のすべてを「Known」制約に置き換えることができることを確認しました。制約を回避することはできませんが、今では1つのキャッチオールを持つだけで、はるかにクリーンです。ありがとう! –
@ JustinL。 [constraint synonyms](https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/constraint-kind.html)を使用することもできます: '既知のns =(Applicative(Foo ns) 、Foldable(Foo ns)、...) 'を実行します。 –
@AlexeyRomanovそれはまだ私に非常にアドホックでun-haskellを感じる。私は、種類の実際のデータコンストラクタに属していない非常にまれな/まれであいまいな使い方しか持たないインスタンスをたくさん投げてしまうかもしれません...それはあまりにも曖昧なクラスとは関係がありませんすべて。そして、私は新しいインスタンスを書くたびに、クラスを追加して作業を複製する必要があります。 –