Ordnen Sie Ord mit quantifizierten Einschränkungen ab (forall a. Ord a => Ord (fa))

10

Mit quantifizierten Einschränkungen kann ich gut ableiten Eq (A f)? Wenn ich jedoch versuche, Ord (A f) abzuleiten, schlägt dies fehl. Ich verstehe nicht, wie quantifizierte Einschränkungen verwendet werden, wenn die Einschränkungsklasse eine Oberklasse hat. Wie leite ich Ord (A f)und andere Klassen ab, die Superklassen haben?

> 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. Ich habe auch ghc Vorschläge 0109-quantifizierte Einschränkungen untersucht . Verwenden von ghc 8.6.5

William Rusnack
quelle

Antworten:

8

Das Problem ist, dass Eqes sich um eine Oberklasse von Ordhandelt und die Einschränkung (forall a. Ord a => Ord (f a))nicht die Einschränkung der Oberklasse beinhaltet Eq (A f), die zum Deklarieren einer Ord (A f)Instanz erforderlich ist .

  • Wir haben (forall a. Ord a => Ord (f a))

  • Wir brauchen Eq (A f), dh (forall a. Eq a => Eq (f a))was nicht durch das impliziert wird, was wir haben.

Lösung: (forall a. Eq a => Eq (f a))Zur OrdInstanz hinzufügen .

(Ich verstehe nicht wirklich, wie sich die von GHC ausgegebene Fehlermeldung auf das Problem bezieht.)

{-# 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)

Oder etwas ordentlicher:

{-# 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)
Li-yao Xia
quelle
Ich war so nah dran deriving instance (forall a. (Eq a, Ord a) => (Eq (f a), Ord (f a))) => Ord (A f). Wissen Sie, warum es einen Unterschied gibt?
William Rusnack
1
Das heißt auch nicht forall a. Eq a => Eq (f a). (In Bezug auf die Logik (A /\ B) => (C /\ D)bedeutet dies nicht A => C)
Li-yao Xia
1
In der Tat ist das, was Sie geschrieben haben, gleichbedeutend mit forall a. Ord a => Ord (f a).
Li-yao Xia
Danke für die Erklärung!
William Rusnack