如何在Haskell中的约束中应用通配符?

Jas*_* Hu 6 haskell

这听起来微不足道,但我无法找出我应该做的事情.

以下是我的类型定义:

data CDeq q a = Shallow (q a)
              | Deep{ hq   ? q a
                    , susp ? CDeq q (q a)
                    , tq   ? q a }
Run Code Online (Sandbox Code Playgroud)

我希望它有一个实例Show.

由于GHC不允许deriving在这里,我只是试着自己写一个:

instance (Show a, Show ????) => Show (CDeq q a) where
    ....
Run Code Online (Sandbox Code Playgroud)

但我卡住了

我不知道如何for all type v, (q v) can be shown在Haskell中表示这一点.

我不能简单地做以下事情:

instance (Show a, Show (q a)) => Show (CDeq q a) where
    ....
Run Code Online (Sandbox Code Playgroud)

因为要显示CDeq q (q a),Show (q (q a))是必需的,然后Show (q (q (q a)))需要,然后继续.

所以我想知道是否有一种语法可以表达我在那里所说的含义?

我曾经认为forall可以解决这个问题,但它不起作用:

instance (Show a, forall v. Show (q v)) => Show (CDeq q a)
Run Code Online (Sandbox Code Playgroud)

Cir*_*dec 10

还有一类Show1Prelude.Extras表示"对于所有类型的v,(q v)可以证明".

class Show1 f where
  showsPrec1 :: Show a => Int -> f a -> ShowS
  default showsPrec1 :: (Show (f a), Show a) => Int -> f a -> ShowS
  showsPrec1 = showsPrec
  ...
Run Code Online (Sandbox Code Playgroud)

您可以使用它来编写show实例CDeq q a.

instance (Show a, Show1 q) => Show (CDeq q a) where
    ....
Run Code Online (Sandbox Code Playgroud)

您将使用showshowsPrecq x您使用show1或使用的地方showsPrec1.

如果您使用这些,您还应该提供实例CDeq q.

instance (Show1 q) => Show1 (CDeq q) where
    showsPrec1 = showsPrec
Run Code Online (Sandbox Code Playgroud)

  • 我什么都不知道.在[constraints](https://hackage.haskell.org/package/constraints)包中有一个`Data.Constraint.Forall`模块.没有太多文件可以使用它; 我确信唯一可以回答是否可以替换类似"Show1"的类的人是[Edward Kmett](http://stackoverflow.com/users/34707/edward-kmett).他留下了一个诱人的暗示,这可能是[这个相关问题的答案](http://stackoverflow.com/a/8082478/414413). (2认同)