ヴァイナルライブラリには型RecAll
ファミリがあります。型レベル リストのすべての型に対して、部分的に適用された制約が真であることを確認してみましょう。たとえば、次のように記述できます。
myShowFunc :: RecAll f rs Show => Rec f rs -> String
そして、それはすべて素敵です。ここで、が不明な制約RecAll f rs c
があり、(ekmett のcontstraintsパッケージから言葉を借りるために)含意を知っている場合、どうすれば を取得できますか?c
c x
d x
RecAll f rs d
私が尋ねる理由は、いくつかの型クラスの制約を満たす必要があるいくつかの関数でレコードを扱っているからです。これを行うために、 existsパッケージのControl.Constraints.Combineモジュールの:&:
コンビネーターを使用しています。(注: の非常に古いバージョンに依存しているため、他のものがインストールされている場合、パッケージはビルドされません。ただし、言及した 1 つのモジュールをコピーするだけでかまいません。) これにより、最小化しながら、いくつかの本当に美しい制約を取得できますタイプクラスのブロイラープレート。例えば:contravariant
RecAll f rs (TypeableKey :&: FromJSON :&: TypeableVal) => Rec f rs -> Value
しかし、この関数の本体内で、より弱い制約を要求する別の関数を呼び出します。次のようになります。
RecAll f rs (TypeableKey :&: TypeableVal) => Rec f rs -> Value
GHC は、2 番目のステートメントが最初のステートメントから続くことを認識できません。そうなのだろうと思いました。私が見ることができないのは、それを具体化して GHC を助けるためにそれを証明する方法です。これまでのところ、私はこれを持っています:
import Data.Constraint
weakenAnd1 :: ((a :&: b) c) :- a c
weakenAnd1 = Sub Dict -- not the Dict from vinyl. ekmett's Dict.
weakenAnd2 :: ((a :&: b) c) :- b c
weakenAnd2 = Sub Dict
これらは正常に動作します。しかし、これは私が立ち往生しているところです:
-- The two Proxy args are to stop GHC from complaining about AmbiguousTypes
weakenRecAll :: Proxy f -> Proxy rs -> (a c :- b c) -> (RecAll f rs a :- RecAll f rs b)
weakenRecAll _ _ (Sub Dict) = Sub Dict
これはコンパイルされません。私が探している効果を得る方法を知っている人はいますか。エラーが参考になる場合は、ここにエラーがあります。また、私はDict
実際のコードに修飾されたインポートを持っているので、それが言及されている理由Constraint.Dict
です:
Table.hs:76:23:
Could not deduce (a c) arising from a pattern
Relevant bindings include
weakenRecAll :: Proxy f
-> Proxy rs -> (a c :- b c) -> RecAll f rs a :- RecAll f rs b
(bound at Table.hs:76:1)
In the pattern: Constraint.Dict
In the pattern: Sub Constraint.Dict
In an equation for ‘weakenRecAll’:
weakenRecAll _ _ (Sub Constraint.Dict) = Sub Constraint.Dict
Table.hs:76:46:
Could not deduce (RecAll f rs b)
arising from a use of ‘Constraint.Dict’
from the context (b c)
bound by a pattern with constructor
Constraint.Dict :: forall (a :: Constraint).
(a) =>
Constraint.Dict a,
in an equation for ‘weakenRecAll’
at Table.hs:76:23-37
or from (RecAll f rs a)
bound by a type expected by the context:
(RecAll f rs a) => Constraint.Dict (RecAll f rs b)
at Table.hs:76:42-60
Relevant bindings include
weakenRecAll :: Proxy f
-> Proxy rs -> (a c :- b c) -> RecAll f rs a :- RecAll f rs b
(bound at Table.hs:76:1)
In the first argument of ‘Sub’, namely ‘Constraint.Dict’
In the expression: Sub Constraint.Dict
In an equation for ‘weakenRecAll’:
weakenRecAll _ _ (Sub Constraint.Dict) = Sub Constraint.Dict