如何确保函数依赖性用于统一依赖的存在类型变量

时间:2017-07-12 20:06:00

标签: haskell functional-dependencies

我有一个类型类,它引入了两种类型之间的函数依赖:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# LANGUAGE GADTs, StandaloneDeriving, UndecidableInstances #-}

class Eq c => Classifiable t c | t -> c where 
    classification :: t -> c

我有很多这类课程,例如对于对,我们使用该对的“分类”是存储在第一个位置的值:

instance Eq a => Classifiable (a,b) a where
    classification = fst

我还有一个使用此类的类型,允许它在其arguemnts中配置类型c时存储类型为t的实例,即c是存在限定的,但是它受到函数依赖的约束,只有一个实际可能的类型由一个可见参数唯一确定,在本例中为t

data Symbol t nt s where
    Terminal ::    (Classifiable t c, Show c, Ord c) =>
                   c                         -> Symbol t nt s
    NonTerminal :: Classifiable t c =>
                   nt -> [Production t nt s] -> Symbol t nt s

我的问题是,当我尝试使用它时,GHC显然不知道对于任何具有给定参数的Symbol对,如果c,则t类型必须相同是。因此,如果我尝试为此类型创建Ord的实例:

deriving instance (Ord c, Ord nt, Classifiable t c) =>   Ord (Symbol t nt s)

我收到以下错误:

Could not deduce (Eq (Symbol t nt s))
  arising from the superclasses of an instance declaration
from the context (Ord c, Ord nt, Classifiable t c)
  bound by the instance declaration
  at src\Text\Parser\ALLStar.hs:16:1-76
In the instance declaration for `Ord (Symbol t nt s)'
C:\development\haskell\delta-parser-git\delta-parser\src\Text\Parser\ALLStar.hs: 16, 1
Couldn't match expected type `c1' with actual type `c2'
  `c2' is a rigid type variable bound by
       a pattern with constructor
         Terminal :: forall t nt s c.
                     (Classifiable t c, Show c, Ord c) =>
                     c -> Symbol t nt s,
       in a case alternative
       at src\Text\Parser\ALLStar.hs:16:1
  `c1' is a rigid type variable bound by
       a pattern with constructor
         Terminal :: forall t nt s c.
                     (Classifiable t c, Show c, Ord c) =>
                     c -> Symbol t nt s,
       in a case alternative
       at src\Text\Parser\ALLStar.hs:16:1
Relevant bindings include
  b1 :: c2 (bound at src\Text\Parser\ALLStar.hs:16:1)
  a1 :: c1 (bound at src\Text\Parser\ALLStar.hs:16:1)
In the second argument of `compare', namely `b1'
In the expression: (a1 `compare` b1)
When typechecking the code for  `compare'
  in a derived instance for `Ord (Symbol t nt s)':
  To see the code I am typechecking, use -ddump-deriv

如何说服编译器理解功能依赖需要两个c绑定是相同的类型?

0 个答案:

没有答案