I have a type class Foo with an associated type:
{-# LANGUAGE TypeFamilies #-}
class Foo a where
type Bar a
foo :: a -> Bar a
Now I want to define a data type that holds one of the associated types, and derive a Show instance for it:
data Baz a = Baz (Bar a) deriving (Show)
This doesn't compile, though, because you can't guarantee that there is a Show instance for Bar a
No instance for (Show (Bar a))
arising from the 'deriving' clause of a data type declaration
I can fix the problem by turning on FlexibleContexts and UndecidableInstances and writing a manual Show instance as follows
{-# 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
But that's not particularly satisfactory, especially when Baz is a more complicated than a simple wrapper around one value, or when I also want to derive instances of other type classes. Is there a way out?
You can use StandaloneDeriving to ask GHC to generate the same Show instance as ever, but with a different context:
{-# 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With