将函数依赖性 class 转换为类型族实例

Converting Functional Dependency class to Type Family instances

是否可以从 fundep 创建类型系列实例 class?例如,假设我有 class

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

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

别想太多了。

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 是双参数 class,但它的第二个参数由第一个参数唯一确定。 C' 是具有关联类型的单参数 class。关联类型被解释为 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

一般来说,我 会写出您在问题中尝试过的那种通用实例,因为此类实例往往会重叠。

函数依赖比类型族 less, um, weird 不过。在所有其他条件相同的情况下,我倾向于更喜欢 fundep。