Search code examples
haskelltype-families

Guarantee that type families will derive certain classes


I have something like the following:

{-# LANGUAGE TypeFamilies #-}

class Configuration c where
    data Pig c
    data Cow c

    parsePig :: GenParser Char st (Pig c)
    parseCow :: GenParser Char st (Cow c)

data Farm c =
    { pigs :: [Pig c]
    , cows :: [Cow c]
    } deriving Show

This fails because of the deriving Show line. I don't know how to force all Configuration instances to ensure that their data Pig and data Cow implementations are all instances of Show.

I know I could make it have showPig and showCow methods and the write out the whole complex show instance, but in reality things are more complex than this and that would be quite a pain.

Is there an easy, elegant way to guarantee that type family instances are themselves instances of certain classes?


Solution

  • You can use StandaloneDeriving to specify the constraints manually just for the Show instance.

    {-# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #-}
    deriving instance (Show (Pig c), Show (Cow c)) => Show (Farm c)
    

    This will still let you have Configuration instances with Cow and Pig that don't implement Show, however, as long as you don't try to show them.