the Coverage Condition fails

断了今生、忘了曾经 提交于 2020-01-15 05:45:06

问题


I have a very simple piece of code as follow:

{-# 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

I got an error related to the Coverage Condition fails for one of the functional dependencies. Do I need to add -XUndecidableInstances to permit this? or how I can fix this problem? Thanks


回答1:


The problem in your case is not Int but e. The Coverage Condition is documented in GHC's manual Sect. 7.6.3.2. Relaxed rules for instance contexts and says:

The Coverage Condition. For each functional dependency, tvsleft -> tvsright, of the class, every type variable in S(tvsright) must appear in S(tvsleft), where S is the substitution mapping each type variable in the class declaration to the corresponding type in the instance declaration.

What does it mean in practise? In your case, your functional dependency says g -> n e, which means that for each instance the types denoted by n and e are unique for the type denoted by g. Now let's say you're defining an instance

instance Graph SomeTypeG SomeTypeN SomeTypeE where
    ...

The coverage condition says that any type variable appearing in SomeTypeE or SomeTypeN must appear in SomeTypeG. What happens if it's not satisfied? Let's suppose a type variable a appears in SomeTypeE but not in SomeTypeG. Then for fixed SomeTypeG we would have an infinite number of possible instances by substituting different types for a.

In your case

instance Graph g Int e where
    ...

e is such a type variable, so by the Coverage Condition it must appear in g, which is not true. Because it doesn't appear there, your definition would imply that Graph g Int Int is an instances, Graph g Int (Maybe Char) is another instance, etc., contradicting the functional dependency that requires that there is precisely one.

If you had defined something like

instance Graph g Int Char where

then it would be OK, as there are no type variables in Int and Char. Another valid instance could be

instance Graph (g2 e) Int e where

where g2 is now of kind * -> *. In this case, e appears in g2 e, which satisfies the Coverage Condition, and indeed, e is always uniquely determined from g2 e.




回答2:


Your functional dependency says that your choice of type g determines your node and element types n and e, respectively. Does it make sense, then, to say that all graph types g (knowing nothing about g) determine the node type to be Int?



来源:https://stackoverflow.com/questions/13538937/the-coverage-condition-fails

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!