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

标签 haskell typeclass derived-class quantified-constraints

通过量化约束,我可以推导出 Eq (A f)正好?但是,当我尝试导出 Ord (A f) 时,它失败了。当约束类具有父类(super class)时,我不明白如何使用量化约束。我如何得出 Ord (A f)和其他具有父类(super class)的类?

> 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。我还检查了ghc proposals 0109-quantified-constraints .使用 ghc 8.6.5

最佳答案

问题是 EqOrd 的父类(super class), 和约束 (forall a. Ord a => Ord (f a))不包含父类(super class)约束 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)
    

    关于haskell - 使用量化约束导出 Ord (forall a. Ord a => Ord (f a)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59743170/

    相关文章:

    haskell - 惯用的 io-streams 目录遍历

    haskell - 如何将一元函数作为带有灵活类型变量的参数传递?

    c++ - 继承的典型问题

    scala - 在 Scala 中的隐式实例中强制执行优先级

    Scala:通用隐式转换器?

    c++ - 获取指向基类 protected 成员函数的函数指针

    java - setZone方法有问题吗?

    Haskell——更容易阅读的显示功能? (用于调试)

    haskell - 如何使用 parsec 解析整数

    haskell - 为什么我收到 "Equations for ... have different numbers of arguments"消息?