Haskell功能依赖项一致性条件:是否需要?使用了吗?

时间:2018-07-02 01:09:57

标签: haskell functional-dependencies

FunDep一致性条件出现在可追溯至Mark P Jones 2000论文的所有文献中。而且它是从FunDeps的数据库理论中继承的。

但是Haskell的FunDeps不太像数据库中的:FunDep ->的意思是:在此类的任何情况下,我保证都会给出一种算法,以从左侧的类参数获取右侧的类参数。 。 (在decl实例中,该算法可能必须克服其约束-然后您需要UndecidableInstances。)

众所周知,GHC对“一致性条件”的实现是伪造的-参见this answer, for example。那是一件好事,我可以写

class TypeEq a a' (b :: Bool) | a a' -> b  where ...
instance TypeEq a a True  where ...
instance (b ~ False) => TypeEq a a' b  where ...

(这需要OverlappingInstances或编译指示,以及Undecidable。)

论文(包括通过CHRs 2006发表的FunDeps中的论文)声称,需要“一致性条件”来确保融合类型推断。并且有一个推断规则,如果您拥有TypeEq alpha1 alpha2 beta1TypeEq alpha1 alpha2 beta2,则可以得出beta1 == beta2,其中==是类型身份,而不仅仅是~的统一性。

但是我看不到有证据表明GHC曾经执行过该规则。这样的约束就可以了(编辑:,即使是对GHC,我在这里的第一个签名也有点太面子了,

f :: (TypeEq a a' True, TypeEq a' a False) => a -> a' -> ()
f _ _ = ()

f 'c' 'd'         -- produces `()` happily

可以定义使用类型族的可比较函数,但不能使用

g :: ((a == b) ~ False, (b == a) ~ True) => a -> b -> ()

(需要TypeOperatorsimport Data.Type.Equality) 对于g 'c' 'd'g 'c' "d",GHC抱怨Couldn't match type 'True with 'False

然后,一致性条件除了令人讨厌之外什么都没有? (Trac上有几张票,这些票的行为很奇怪。)

有人依靠吗?还是在尴尬的重叠情况下使用它来验证其实例?

添加::通过翻转类型参数,您可能会认为f的签名正在作弊。此签名(我的初始帖子)

f :: (TypeEq a a' True, TypeEq a a' False) => a -> a' -> ()

被拒绝Couldn't match type 'False with 'True。因此,看起来GHC正在应用“带有相同参数的调用”推断规则。

但是这使args不翻转就可以了(因为两个签名太远了?)

f1 :: (TypeEq a a' False) => a -> a' -> [()]
f1 _ _ = [()]
f2 :: (TypeEq a a' True) => a -> a' -> [()]
f2 _ _ = [()]
-- f3 :: (TypeEq a a' f2', TypeEq a a' f1') => a -> a' -> [()]  
f3 x y = f1 x y ++ f2 x y

也就是说,如果我f3签名,就可以了。 (并且无论我为f3尝试使用什么签名,都会拒绝Overlapping instances for TypeEq a b 'True arising from a use of ‘f2’;以及其他消息。)

0 个答案:

没有答案