あなたの場合の問題はそうではありませIntんe。カバレッジ条件は、GHC のマニュアルの節に記載されています。7.6.3.2. インスタンスコンテキストのルールを緩和し、次のように述べています。
カバレッジ条件。クラスの各関数依存関係 tvs left -> tvs rightについて、S(tvs right )内のすべての型変数が S (tvs left ) に出現する必要があります。ここで、S は、クラス宣言内の各型変数を対応する型変数にマッピングする置換です。インスタンス宣言を入力します。
実際にはどういう意味ですか?あなたの場合、あなたの機能的依存関係は と言っていますg -> n e。これは、各インスタンスについて、 で示されるタイプが で示されるタイプに対して一意でnあることを意味します。ここで、インスタンスを定義しているとしましょうeg
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 eeg2 e