Получение экземпляров с помощью TypeFamilies
У меня есть класс типа 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
Я могу исправить проблему, включив 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
Но это не особенно удовлетворительно, особенно когда Baz
является более сложным, чем простая оболочка вокруг одного значения или когда я также хочу получить экземпляры других классов типов. Есть ли выход?
Ответы
Ответ 1
Вы можете использовать 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)