10

我有一个Foo具有关联类型的类型类:

{-# LANGUAGE TypeFamilies #-}

class Foo a where
    type Bar a
    foo :: a -> Bar a

现在我想定义一个包含关联类型之一的数据类型,并Show为其派生一个实例:

data Baz a = Baz (Bar a) deriving (Show)

但是,这不会编译,因为你不能保证有一个Show实例Bar a

No instance for (Show (Bar a))
  arising from the 'deriving' clause of a data type declaration

我可以通过打开并编写手动实例来解决问题FlexibleContextsUndecidableInstances如下Show所示

{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}

data Baz a = Bar a

instance (Show a, Show (Bar a)) => Show (Baz a) where
    showsPrec _ (Baz x) = showString "Baz " . shows x

但这并不是特别令人满意,尤其是当Baz它比围绕一个值的简单包装器更复杂时,或者当我还想派生其他类型类的实例时。有出路吗?

4

1 回答 1

15

您可以使用StandaloneDeriving来要求 GHC 生成与Show以往相同的实例,但使用不同的上下文:

{-# LANGUAGE FlexibleContexts, StandaloneDeriving, TypeFamilies, UndecidableInstances #-}

class Foo a where
    type Bar a
    foo :: a -> Bar a

data Baz a = Baz (Bar a)
deriving instance Show (Bar a) => Show (Baz a)
于 2012-10-30T17:57:53.443 回答