使用TypeFamilies派生实例

Chr*_*lor 10 haskell types type-families

我有一个类型类Foo与关联类型:

{-# LANGUAGE TypeFamilies #-}

class Foo a where
    type Bar a
    foo :: a -> Bar a
Run Code Online (Sandbox Code Playgroud)

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

data Baz a = Baz (Bar a) deriving (Show)
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译,因为您无法保证有Show实例Bar a

No instance for (Show (Bar a))
  arising from the 'deriving' clause of a data type declaration
Run Code Online (Sandbox Code Playgroud)

我可以修复通过打开的问题FlexibleContexts,并UndecidableInstances和写作手册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
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*ner 15

您可以使用StandaloneDerivingGHC来生成相同的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)
Run Code Online (Sandbox Code Playgroud)