[haskell] 정량화 된 구속 조건을 가진 Ord 도출 (forall a. Ord a => Ord (fa))

정량화 된 제약 조건으로 Eq (A f)잘 파생 될 수 있습니까? 그러나 Ord (A f)를 얻으려고하면 실패합니다. 제약 조건 클래스에 수퍼 클래스가있을 때 정량화 된 제약 조건을 사용하는 방법을 이해하지 못합니다. 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)'

추신. 또한 ghc 제안서 0109-quantified-constraints 도 검토했습니다 . ghc 8.6.5 사용



답변

문제는 Eq의 수퍼 클래스이며 Ord제약 조건 (forall a. Ord a => Ord (f a))에는 인스턴스 Eq (A f)를 선언하는 데 필요한 수퍼 클래스 제약 조건 이 수반되지 않습니다 Ord (A f).

  • 우리는 (forall a. Ord a => Ord (f a))

  • 우리는 필요 Eq (A f), 즉, (forall a. Eq a => Eq (f a))우리는 무엇을 암시하지 않는.

솔루션 : 인스턴스에 추가 (forall a. Eq a => Eq (f a))하십시오 Ord.

(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)

아니면 좀 더 깔끔하게 :

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


답변