Haskell 如何确保函数依赖关系用于统一依赖的存在类型变量
我有一个typeclass,它在两种类型之间引入了函数依赖关系:Haskell 如何确保函数依赖关系用于统一依赖的存在类型变量,haskell,functional-dependencies,Haskell,Functional Dependencies,我有一个typeclass,它在两种类型之间引入了函数依赖关系: {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} {-# LANGUAGE GADTs, StandaloneDeriving, UndecidableInstances #-} class Eq c => Classifiable t c | t -> c where classificati
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# LANGUAGE GADTs, StandaloneDeriving, UndecidableInstances #-}
class Eq c => Classifiable t c | t -> c where
classification :: t -> c
我有许多此类实例,例如,对于pairs,我们使用pairs的“分类”是存储在第一个位置的值:
instance Eq a => Classifiable (a,b) a where
classification = fst
我还有一个类型,当在其参数中配置了typet
时,该类型使用该类允许它存储typec
的实例,即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
s,如果t
为,则类型c
必须相同。因此,如果我尝试为此类型创建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
绑定的类型相同?我猜函数依赖性不会引入c1~c2
约束——可以说,它们应该引入约束。我会考虑切换到类型族而不是FUNDEPS。“我怎样才能说服编译器理解这两个C绑定需要由函数依赖性来实现?”-----用<代码> unSaveCoSerCE < /代码>。(你也可以使用关联类型而不是fundeps。)我想我刚才回答了一个关于这个的问题,但现在找不到。但基本上,你希望陈述的事实是不真实的;如果是,两个不同的模块可能会有两个相同类型的不同实例,例如Classifiable Int Bool
和Classifiable Int String
,第三个模块导入这两个模块将能够证明Bool~String
。