GHC 9 中量化约束行为的变化
Change in Behaviour of Quantified Constraints in GHC 9
以前,为了像 Ord
这样对类型 class 使用量化约束,您必须像这样在实例中包含 superclass:
newtype A f = A (f Int)
deriving instance (forall a. Eq a => Eq (f a)) => Eq (A f)
deriving instance (forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) => Ord (A f)
(这实际上正是问题中给出的解决方案)。
然而,在 GHC 9 中,上述代码不起作用。它因以下错误而失败:
• Could not deduce (Eq (f a))
from the context: (forall a. Eq a => Eq (f a),
forall a. Ord a => Ord (f a))
bound by a stand-alone deriving instance declaration:
forall (f :: * -> *).
(forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) =>
Ord (A f)
or from: Eq a
bound by a quantified context
• In the ambiguity check for a stand-alone deriving instance declaration
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the stand-alone deriving instance for
‘(forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) =>
Ord (A f)’
很遗憾,AllowAmbiguousTypes
建议无效。 (你得到同样的错误,随后 class 上的每个方法都出现同样的错误)
有人知道解决这个问题的方法吗?
解决它的一个简单方法是将第二个派生子句更改为:
deriving instance (Eq (A f), forall a. Ord a => Ord (f a)) => Ord (A f)
虽然我还没有很好的解释为什么会这样。
以前,为了像 Ord
这样对类型 class 使用量化约束,您必须像这样在实例中包含 superclass:
newtype A f = A (f Int)
deriving instance (forall a. Eq a => Eq (f a)) => Eq (A f)
deriving instance (forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) => Ord (A f)
(这实际上正是
然而,在 GHC 9 中,上述代码不起作用。它因以下错误而失败:
• Could not deduce (Eq (f a))
from the context: (forall a. Eq a => Eq (f a),
forall a. Ord a => Ord (f a))
bound by a stand-alone deriving instance declaration:
forall (f :: * -> *).
(forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) =>
Ord (A f)
or from: Eq a
bound by a quantified context
• In the ambiguity check for a stand-alone deriving instance declaration
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the stand-alone deriving instance for
‘(forall a. Eq a => Eq (f a), forall a. Ord a => Ord (f a)) =>
Ord (A f)’
很遗憾,AllowAmbiguousTypes
建议无效。 (你得到同样的错误,随后 class 上的每个方法都出现同样的错误)
有人知道解决这个问题的方法吗?
解决它的一个简单方法是将第二个派生子句更改为:
deriving instance (Eq (A f), forall a. Ord a => Ord (f a)) => Ord (A f)
虽然我还没有很好的解释为什么会这样。