是否可以为此树类型派生“ Ord”的实现?如果没有,为什么?

时间:2019-05-17 18:47:13

标签: haskell

我定义了以下非常普通的树类型:

data YTree f g a = YNode (f a (g (YTree f g a)))

我已经定义了函子实例,如下所示(以证明可以使用):

instance (Bifunctor f, Functor g) => Functor (YTree f g) where
    fmap f (YNode m) = YNode $ bimap f (fmap (fmap f)) m

然后,我成功地导出了一些实例(使用StandaloneDerivingExplicitForAllQuantifiedConstraints):

deriving instance (Show a, forall x y. (Show x, Show y) => Show (f x y), forall z. Show z => Show (g z)) => Show (YTree f g a)
deriving instance (Read a, forall x y. (Read x, Read y) => Read (f x y), forall z. Read z => Read (g z)) => Read (YTree f g a)
deriving instance (Eq a, forall x y. (Eq x, Eq y) => Eq (f x y), forall z. Eq z => Eq (g z)) => Eq (YTree f g a)

但是,以下deriving instance子句在包含时会引发错误:

deriving instance (Ord a, forall x y. (Ord x, Ord y) => Ord (f x y), forall z. Ord z => Ord (g z)) => Ord (YTree f g a)

Data\Tree\Generalized.hs:32:1: error:
    * Could not deduce (Ord z)
        arising from the superclasses of an instance declaration
      from the context: (Ord a,
                         forall x y. (Ord x, Ord y) => Ord (f x y),
                         forall z. Ord z => Ord (g z))
        bound by the instance declaration
        at Data\Tree\Generalized.hs:32:1-119
      or from: Eq z
        bound by a quantified context at Data\Tree\Generalized.hs:1:1
      Possible fix: add (Ord z) to the context of a quantified context
    * In the instance declaration for `Ord (YTree f g a)'
   |
32 | deriving instance (Ord a, forall x y. (Ord x, Ord y) => Ord (f x y), forall z. Ord z => Ord (g z)) => Ord (YTree f g a)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

以及另一个错误。

据我所见,实现方式很简单:

instance (Ord a, forall x y. (Ord x, Ord y) => Ord (f x y), forall z. Ord z => Ord (g z)) => Ord (YTree f g a) where
    compare (YNode x) (YNode y) = compare x y

这会产生相同的错误。

有可能得出这个吗?为什么现在不起作用?甚至有可能实现吗?我错了吗?

1 个答案:

答案 0 :(得分:3)

deriving instance
  ( Ord a, forall x y. (Ord x, Ord y) => Ord (f x y), forall z. Ord z => Ord (g z)
  , Eq  a, forall x y. (Eq  x, Eq  y) => Eq  (f x y), forall z. Eq  z => Eq  (g z)
  ) => Ord (YTree f g a)

会编译,但我不知道为什么我们需要Eq约束。