gpt4 book ai didi

haskell - 为什么在 Haskell 中选择类型类实例时不考虑上下文?

转载 作者:行者123 更新时间:2023-12-02 08:25:56 24 4
gpt4 key购买 nike

我明白当有

instance (Foo a) => Bar a
instance (Xyy a) => Bar a

GHC 不考虑上下文,并且实例被报告为重复。

违反直觉的是,(我猜)在选择实例之后,它仍然需要检查上下文是否匹配,如果不匹配,则丢弃该实例。那么为什么不颠倒顺序,丢弃上下文不匹配的实例,然后继续处理剩余的集合。

这会在某种程度上变得棘手吗?我知道它如何预先导致更多的约束解析工作,但就像有 UndecidableInstances/IncoherentInstances 一样,不能有 ConsiderInstanceContexts 吗? “我知道我在做什么”?

最佳答案

这打破了开放世界的假设。假设:

class B1 a
class B2 a
class T a

如果我们允许约束来消除实例的歧义,我们可以写

instance B1 a => T a
instance B2 a => T a

并且可以写

instance B1 Int

现在,如果我有

f :: T a => a

然后f::Int 就可以工作了。但是,开放世界假设表明,一旦某件事起作用,添加更多实例就无法破坏它。我们的新系统不遵守:

instance B2 Int

将使f::Int变得不明确。应使用 T 的哪种实现?

另一种说法是你破坏了连贯性。对于类型类来说,一致意味着只有一种方法可以满足给定的约束。在正常的 Haskell 中,约束 c 只有一种实现。即使有重叠的实例,一致性通常也是成立的。这个想法是 instance T ainstance {-# OVERLAPPING #-} T Int 不会破坏连贯性,因为 GHC 不能被欺骗而使用前一个实例后者会做的地方。 (你可以用孤儿来欺骗它,但你不应该。)连贯性,至少对我来说,似乎有些可取。从某种意义上说,类型类的用法是“隐藏的”,强制它明确是有意义的。您还可以使用 IncoherentInstances 和/或 unsafeCoerce 来破坏连贯性,但是,您知道。

在类别理论中,类别Constraint很薄:一个Constraint最多有一个实例/箭头 到另一个。我们首先构造两个箭头 a : () => B1 Intb : () => B2 Int,然后通过添加新箭头 x_Int 来打破稀疏性: B1 Int => T Int, y_Int : B2 Int => T Int 这样 x_Int 。 ay_Int 。 b 都是不相同的箭头 () => T Int。菱形继承(钻石问题),有人吗?

关于haskell - 为什么在 Haskell 中选择类型类实例时不考虑上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26885067/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com