Xuất phát Ord với các ràng buộc định lượng (forall a. Ord a => Ord (fa))


10

Với các ràng buộc định lượng tôi có thể rút ra Eq (A f)tốt không? Tuy nhiên, khi tôi cố gắng lấy Ord (A f) thì thất bại. Tôi không hiểu làm thế nào để sử dụng các ràng buộc được định lượng khi lớp ràng buộc có một siêu lớp. Làm thế nào để tôi lấy được Ord (A f)và các lớp khác có siêu lớp?

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

Tái bút Tôi cũng đã kiểm tra các đề xuất ghc 0109 định lượng . Sử dụng ghc 8.6.5

Câu trả lời:


8

Vấn đề là đó Eqlà một siêu lớp Ordvà ràng buộc (forall a. Ord a => Ord (f a))không đòi hỏi ràng buộc của siêu lớp Eq (A f)mà cần phải khai báo một Ord (A f)thể hiện.

  • Chúng ta có (forall a. Ord a => Ord (f a))

  • Chúng ta cần Eq (A f), tức là, (forall a. Eq a => Eq (f a))không được ngụ ý bởi những gì chúng ta có.

Giải pháp: thêm (forall a. Eq a => Eq (f a))vào Ordví dụ.

(Tôi thực sự không hiểu thông báo lỗi do GHC đưa ra liên quan đến vấn đề như thế nào.)

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

Hoặc gọn gàng hơn một chút:

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

Tôi đã rất gần gũi với deriving instance (forall a. (Eq a, Ord a) => (Eq (f a), Ord (f a))) => Ord (A f). Bạn có biết tại sao có sự khác biệt?
William Rusnack

1
Điều đó cũng không ngụ ý forall a. Eq a => Eq (f a). (xem dưới dạng logic (A /\ B) => (C /\ D)không ngụ ý A => C)
Li-yao Xia

1
Trong thực tế những gì bạn viết là tương đương với forall a. Ord a => Ord (f a).
Li-yao Xia

Cảm ơn đã giải thích!
William Rusnack
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.