将Functional Dependency类转换为Type Family实例

时间:2017-05-06 14:41:58

标签: haskell functional-dependencies type-families

是否可以从fundep类创建类型族实例?例如,让我们说我有班级

class A a b | a -> b

包含一些实例(导入外部库)并希望为类型系列

创建所有相应的实例
type family A' a :: *

这样A' a ~ b iff A a b,而无需手动复制和修改外部来源的实例。

我该怎么做(如果可能的话)?

到目前为止我最有希望的尝试,

class A' a where
    type A'_b a :: *

instance forall a b. A a b => A' a where
    type A'_b a = b

给出错误消息

    The RHS of an associated type declaration mentions ‘b’
      All such variables must be bound on the LHS

所以,我的猜测是答案是否定的? :/

1 个答案:

答案 0 :(得分:2)

不要过分思考它。

class C a b | a -> b
instance C T U

大致转化为

class C' a where
    type B a
instance C' T where
    type B T = U

他们在语义上有些不同,即使他们的行为方式相似。 C是一个双参数类,但它的第二个参数由第一个参数唯一确定。 C'是具有关联类型的单参数类。相关类型被解释为FC强制系统的顶级公理,而fundeps基本上只影响统一。

可以在两种样式之间进行转换,但您必须使用newtype来绑定type等式中的变量。

newtype WrappedB a = WrappedB { unwrapB :: B a }
instance C' a => C a (WrappedB a)  -- you can't use a type synonym family in an instance

newtype Wrap a b = Wrap { unWrap :: a }
instance C a b => C' (Wrap a b) where
    type B (Wrap a b) = b  -- b needs to be bound on the LHS of this equation

一般情况下,我don't advise撰写您在问题中尝试过的那种通用实例,因为此类实例有重叠的倾向。

但是,功能依赖性是less, um, weird而不是类型族。在所有其他条件相同的情况下,我倾向于选择一个fundep。