覆盖条件失败

chi*_*k10 2 haskell

我有一段非常简单的代码如下:

{-# 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
Run Code Online (Sandbox Code Playgroud)

我得到一个与Coverage条件相关的错误,其中一个函数依赖项失败了.我是否需要添加-XUndecidableInstances以允许此操作?或者我如何解决这个问题?谢谢

Pet*_*lák 5

你的情况的问题不是Int而是e.覆盖条件记录在GHC的手册 Sect中.7.6.3.2.例如上下文的宽松规则并说:

覆盖条件.对于每个功能依赖,电视左侧 - > 右侧电视,S中的每个类型变量(右侧电视)必须出现在S(左侧电视)中,其中S是将类声明中的每个类型变量映射到相应的替换在实例声明中输入.

这在实践中意味着什么?在你的情况,你的函数依赖表示g -> n e,这意味着每个实例的类型记ne是由表示的类型独特g.现在让我们说你正在定义一个实例

instance Graph SomeTypeG SomeTypeN SomeTypeE where
    ...
Run Code Online (Sandbox Code Playgroud)

覆盖条件表示出现在SomeTypeESomeTypeN必须出现的任何类型变量SomeTypeG.如果不满意会怎么样?我们假设一个类型变量a出现在SomeTypeE但不在SomeTypeG.然后,对于固定,SomeTypeG我们将通过替换不同类型来获得无限数量的可能实例a.

在你的情况下

instance Graph g Int e where
    ...
Run Code Online (Sandbox Code Playgroud)

e是一个这样的类型变量,所以通过Coverage Condition它必须出现g,这不是真的.因为它没有出现在那里,你的定义意味着它Graph g Int Int是一个实例,Graph g Int (Maybe Char)是另一个实例等,与需要恰好有一个的功能依赖相矛盾.

如果你已经定义了类似的东西

instance Graph g Int Char where
Run Code Online (Sandbox Code Playgroud)

那将是美好的,因为有没有类型变量IntChar.另一个有效的例子可能是

instance Graph (g2 e) Int e where
Run Code Online (Sandbox Code Playgroud)

g2现在在哪里* -> *.在这种情况下,e出现在g2 e满足覆盖条件的情况下,实际上,e始终是唯一确定的g2 e.