あなたの場合の問題はそうではありませInt
んe
。カバレッジ条件は、GHC のマニュアルの節に記載されています。7.6.3.2. インスタンスコンテキストのルールを緩和し、次のように述べています。
カバレッジ条件。クラスの各関数依存関係 tvs left -> tvs rightについて、S(tvs right )内のすべての型変数が S (tvs left ) に出現する必要があります。ここで、S は、クラス宣言内の各型変数を対応する型変数にマッピングする置換です。インスタンス宣言を入力します。
実際にはどういう意味ですか?あなたの場合、あなたの機能的依存関係は と言っていますg -> n e
。これは、各インスタンスについて、 で示されるタイプが で示されるタイプに対して一意でn
あることを意味します。ここで、インスタンスを定義しているとしましょうe
g
instance Graph SomeTypeG SomeTypeN SomeTypeE where
...
カバレッジ条件は、SomeTypeE
またはに現れる型変数は にSomeTypeN
現れなければならないことを示していSomeTypeG
ます。満たされない場合はどうなりますか?型変数が に表示され、 にはa
表示されSomeTypeE
ないとしSomeTypeG
ます。次に、固定SomeTypeG
の場合、さまざまなタイプを置き換えることにより、可能なインスタンスを無限に持つことができますa
。
あなたの場合
instance Graph g Int e where
...
e
はそのような型変数であるため、カバレッジ条件によって に表示される必要がありますがg
、これは正しくありません。そこに表示されないため、定義はそれがインスタンスである、別のインスタンスであるなどを意味し、Graph g Int Int
正確Graph g Int (Maybe Char)
に1つ存在することを必要とする機能依存性と矛盾します。
次のようなものを定義した場合
instance Graph g Int Char where
Int
と には型変数がないため、問題ありませんChar
。別の有効なインスタンスは
instance Graph (g2 e) Int e where
どこにg2
あるのですか* -> *
?この場合、はカバレッジ条件を満たすにe
現れ、実際にから常に一意に決定されます。g2 e
e
g2 e