Sayısal Kısıtlamalarla Ord türevi (forall a. Ord a => Ord (fa))


10

Nicel kısıtlamalar ile Eq (A f)iyi para cezası alabilir miyim? Ancak, Ord (A f) 'yi türetmeye çalıştığımda başarısız olur. Kısıtlama sınıfının bir üst sınıfı olduğunda nicelenmiş kısıtlamaları nasıl kullanacağımı anlamıyorum. Ord (A f)Üst sınıf olan diğer sınıfları nasıl türetebilirim ?

> 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. Ayrıca ghc teklifleri 0109-nicelleştirilmiş-kısıtlamaları da inceledim . Ghc 8.6.5 kullanma

Yanıtlar:


8

Sorun şu ki Eqbir süper sınıftır Ordve kısıtlama (forall a. Ord a => Ord (f a)), Eq (A f)bir Ord (A f)örneği bildirmek için gerekli olan süper sınıf kısıtlamasını gerektirmez .

  • Sahibiz (forall a. Ord a => Ord (f a))

  • İhtiyacımız Eq (A f), yani, (forall a. Eq a => Eq (f a))sahip olduğumuz şey tarafından ima edilmiyor.

Çözüm: Eklenti (forall a. Eq a => Eq (f a))için Ordörneğin.

(GHC tarafından verilen hata mesajının sorunla nasıl ilişkili olduğunu gerçekten anlamıyorum.)

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

Ya da biraz daha düzenli bir şekilde:

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

Çok yakındım deriving instance (forall a. (Eq a, Ord a) => (Eq (f a), Ord (f a))) => Ord (A f). Neden bir fark olduğunu biliyor musunuz?
William Rusnack

1
Bu da demek değildir forall a. Eq a => Eq (f a). (mantık açısından bakıldığında (A /\ B) => (C /\ D)ima edilmez A => C)
Li-yao Xia

1
Aslında yazdıklarınız eşdeğerdir forall a. Ord a => Ord (f a).
Li-yao Xia

Açıklama için teşekkürler!
William Rusnack
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.