简体   繁体   English

使用量化约束导出 Ord(forall a.Ord a => Ord (fa))

[英]Derive Ord with Quantified Constraints (forall a. Ord a => Ord (f a))

With quantified constraints I can derive Eq (A f) just fine?有了量化的约束,我可以很好地推导出Eq (A f)吗? However, when I try to derive Ord (A f) it fails.但是,当我尝试推导 Ord (A f) 时,它失败了。 I do not understand how to use quantified constraints when the constraint class has a superclass.当约束类具有超类时,我不明白如何使用量化约束。 How do I derive Ord (A f) and other classes that have superclasses?如何派生Ord (A f)和其他具有超类的类?

> newtype A f = A (f Int)
> deriving instance (forall a. Eq a => Eq (f a)) => Eq (A f)
> deriving instance (forall a. Ord a => Ord (f a)) => Ord (A f)
<interactive>:3:1: error:
    • Could not deduce (Ord a)
        arising from the superclasses of an instance declaration
      from the context: forall a. Ord a => Ord (f a)
        bound by the instance declaration at <interactive>:3:1-61
      or from: Eq a bound by a quantified context at <interactive>:1:1
      Possible fix: add (Ord a) to the context of a quantified context
    • In the instance declaration for 'Ord (A f)'

PS.附注。 I have also examined ghc proposals 0109-quantified-constraints .我还检查了ghc 提案 0109-quantified-constraints Using ghc 8.6.5使用 ghc 8.6.5

The problem is that Eq is a superclass of Ord , and the constraint (forall a. Ord a => Ord (fa)) does not entail the superclass constraint Eq (A f) that's required to declare an Ord (A f) instance.问题是EqOrd的超类,并且约束(forall a. Ord a => Ord (fa))不包含声明Ord (A f)实例所需的超类约束Eq (A f)

  • We have (forall a. Ord a => Ord (fa))我们有(forall a. Ord a => Ord (fa))

  • We need Eq (A f) , ie, (forall a. Eq a => Eq (fa)) , which is not implied by what we have.我们需要Eq (A f) ,即(forall a. Eq a => Eq (fa)) ,这不是我们所拥有的。

Solution: add (forall a. Eq a => Eq (fa)) to the Ord instance.解决方案:将(forall a. Eq a => Eq (fa))Ord实例中。

(I don't actually understand how the error message given by GHC relates to the problem.) (我实际上不明白 GHC 给出的错误消息与问题有何关联。)

{-# LANGUAGE QuantifiedConstraints, StandaloneDeriving, UndecidableInstances, FlexibleContexts #-}

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)

Or a little more tidily:或者更整洁一点:

{-# LANGUAGE ConstraintKinds, RankNTypes, KindSignatures, QuantifiedConstraints, StandaloneDeriving, UndecidableInstances, FlexibleContexts #-}

import Data.Kind (Constraint)

type Eq1 f = (forall a. Eq a => Eq (f a) :: Constraint)
type Ord1 f = (forall a. Ord a => Ord (f a) :: Constraint)  -- I also wanted to put Eq1 in here but was getting some impredicativity errors...

-----

newtype A f = A (f Int)
deriving instance Eq1 f => Eq (A f)
deriving instance (Eq1 f, Ord1 f) => Ord (A f)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM