私のコードには、このクラスに似たものがあります。私の状況では、クラスFooに別のパラメーターとして'を追加することは意味がありません。
class Foo a where
type FCtx a a' :: Constraint
type FCtx a a' = ()
f :: (FCtx a a') => a -> a'
data D b = D b
instance (Integral b) => Foo (D b) where
-- the next line does not compile because b' does not appear on the LHS
type FCtx (D b) a' = (a' ~ D b', Integral b')
f (D x) = D $ fromIntegral x
のこの特定のインスタンスについては、このように関連付けFoo
たいと思います。a'
この作業を行うために私が思いついた唯一の方法は、「明らかな」タイプの同義語を持つ「ダミー」クラスを追加することです。
class DClass d where
type DType d
instance DClass (D b) where
type DType (D b) = b
Foo
インスタンスは次のようになります。
instance (Integral b) => Foo (D b) where
type FCtx (D b) a' = (a' ~ D (DType a'), Integral (DType a'))
f (D x) = D $ fromIntegral x
問題は、(D b)がbを決定する型の同義語/関数従属性を表現するためだけに、特定のデータ型のクラス全体(およびインスタンス)を作成する必要があったことです。タイプパラメータを常に意味したいので、このクラスの他のインスタンスはありません。DType a'
D b
代わりに私がやりたいことは次のようなものです:
type DParam (D b) = b
instance (Integral b) => Foo (D b) where
type FCtx (D b) a' = (a' ~ D (DParam a'), Integral (DParam a'))
f (D x) = D $ fromIntegral x
または、型の同義語をまったく使用せずに、この制約を表現するためのより良い方法もあります。これを達成するためだけに、単一のインスタンスと同義の型を持つ(オープン)クラスを作成することを余儀なくされるのはばかげているようです。他の人が私が意図しない新しいインスタンスを作成する可能性があるのは危険です。
少なくとも、「パターン一致型の同義語」をDClass
上記のクラス/インスタンスに変換する標準的な方法はないでしょうか。