2

次のような非常に単純なコードがあります。

{-# LANGUAGE
    MultiParamTypeClasses,
    FunctionalDependencies,
    FlexibleInstances,
    FlexibleContexts
#-}

class Graph g n e | g -> n e where
    nodes           :: g -> [n]                             
    edge            :: g -> (n,n) -> Maybe e                

instance Graph g Int e where
    nodes g = []
    edge g (n1,n2) = Nothing

機能依存関係の 1 つでカバレッジ条件が失敗することに関連するエラーが発生しました。これを許可するには、-XUndecidableInstances を追加する必要がありますか? またはどうすればこの問題を解決できますか?ありがとう

4

2 に答える 2

5

あなたの場合の問題はそうではありませInte。カバレッジ条件は、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

于 2013-02-01T18:40:20.737 に答える
1

関数従属性は、タイプgの選択によって、ノードと要素のタイプnとeがそれぞれ決定されることを示しています。では、すべてのグラフタイプg(gについて何も知らない)がノードタイプをIntとして決定すると言うのは理にかなっていますか?

于 2013-02-01T16:35:16.347 に答える