将功能依赖类转换为类型族实例

Hju*_*lle 13 haskell type-families functional-dependencies

是否可以从fundep类创建类型族实例?例如,假设我有课

\n\n
class A a b | a -> b\n
Run Code Online (Sandbox Code Playgroud)\n\n

有一些实例(导入外部库)并希望为该类型系列创建所有相应的实例

\n\n
type family A' a :: *\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样A' a ~ biff A a b,无需从外部源手动复制和修改实例。

\n\n

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

\n\n
\n\n

迄今为止我最有希望的尝试,

\n\n
class A' a where\n    type A'_b a :: *\n\ninstance forall a b. A a b => A' a where\n    type A'_b a = b\n
Run Code Online (Sandbox Code Playgroud)\n\n

给出错误消息

\n\n
    The RHS of an associated type declaration mentions \xe2\x80\x98b\xe2\x80\x99\n      All such variables must be bound on the LHS\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么,我的猜测是答案是否定的?:/

\n

Ben*_*son 4

别想太多。

class C a b | a -> b
instance C T U
Run Code Online (Sandbox Code Playgroud)

大致翻译为

class C' a where
    type B a
instance C' T where
    type B T = U
Run Code Online (Sandbox Code Playgroud)

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

可以在两种样式之间进行转换,但必须使用 anewtype来绑定方程中的变量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
Run Code Online (Sandbox Code Playgroud)

一般来说,我不建议编写您在问题中尝试过的那种通用实例,因为此类实例有重叠的趋势。

不过,函数依赖性比类型族要少一些,嗯,奇怪。在所有其他条件相同的情况下,我倾向于选择fundep。