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

Haskell 将函数依赖类转换为类型族实例,haskell,functional-dependencies,type-families,Haskell,Functional Dependencies,Type Families,是否可以从fundep类创建类型族实例?例如,假设我有这个班 class A a b | a -> b 使用某些实例(导入了外部库),并希望为类型族创建所有相应的实例 type family A' a :: * 这样,A'A~biffA A b,而无需从外部源手动复制和修改实例 我该怎么做(如果可能的话) 我迄今为止最有希望的尝试 class A' a where type A'_b a :: * instance forall a b. A a b => A' a

是否可以从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
那么,我猜答案是否定的/

不要想得太多

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强制系统的顶级公理,而FundeP基本上只影响统一

可以在这两种样式之间进行转换,但必须使用
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
一般来说,我写的是你在问题中尝试过的那种泛型实例,因为这样的实例有重叠的倾向


不过,函数依赖项比类型族更重要。在所有其他条件相同的情况下,我倾向于选择fundep。

但是否可以创建
C'
的实例
C
的给定实例(来自外部库),而不必手动枚举它们?为什么要这样做?难道你不能只写带有
C
约束的函数吗?一部分是因为它应该是可能的,函数依赖关系包含了类型族所需的所有信息。据我所知,它们是等价的,所以应该可以在它们之间进行转换。另一方面,我正在与类型检查器进行一些奇怪的较量,我相信使用
*
类而不是约束(
对于所有a.aab=>a
vs
a'a
)将向编译器显示我实际上并没有给它一个多态值。@Hjulle这是可能的,但正如我所说的,您必须使用一个新类型。见我的编辑answer@Hjulle我不太明白你的意思
Wrap
C
的实例打包为
C'
的实例。您不需要做任何工作来返回另一种方式,因为已经有了
cab
的实例。fundep确保对于给定的
a
,对于
Wrap
,只能有一个
C'
实例,即
Wrap a b
。以下是一个非常相关的帖子: