4

ADT 是免费的单子:

data Free f r = Free (f (Free f r)) | Pure r

我希望它派生Show出来,以便在使用它时可以将其打印出来。例如,如果我有以下内容:

data T next = A next | B next deriving (Show)
aa = Free $ A $ Free $ B $ Pure ()

就像现在一样,如果我添加deriving (Show)FreeADT,我会收到以下错误:

No instance for (Show (f (Free f r)))
      arising from the first field of ‘Free’ (type ‘f (Free f r)’)
    Possible fix:
      use a standalone 'deriving instance' declaration,
        so you can specify the instance context yourself
    When deriving the instance for (Show (Free f r))

我想show aa生成一个可打印的字符串。这可能吗?

4

2 回答 2

7

正如错误消息所暗示的那样,您需要使用一个名为 的扩展StandaloneDeriving,它允许您明确指定派生实例的约束。您还需要启用UndecidableInstances以支持您实际需要的约束。

{-# LANGUAGE StandaloneDeriving, UndecidableInstances #-}

deriving instance (Show r, Show (f (Free f r))) => Show (Free f r)
于 2015-03-03T21:55:00.063 回答
2

一种可能的替代方法是使用prelude-extras中的类UndecidableInstances,但这种方法不太适用。这为您提供了一个很好的约束,但让您编写自己的(简单)实例。Show1(Show1 f, Show r)

于 2015-03-04T00:43:12.743 回答