Ensure that family types receive specific 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 due to the string deriving Show. I do not know how to make all the copies Configurationto ensure that their implementation data Pigand data Cow- all instances Show.

I know that I could use methods showPigand showCowwrite out the whole complex instance Show, but in fact, things are more complicated than that, and it will be pretty painful.

Is there a simple and elegant way to ensure that instances of a type family are themselves instances of certain classes?

+5
source share
2 answers

StandaloneDeriving Show.

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

Configuration Cow Pig, Show, , Show .

+8

, Configuration Pig c Cow c Show, - , :

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

class (Show (Pig c), Show (Cow c)) => Configuration c where
    data Pig c
    data Cow c

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

EDIT:

@hammar, . - StandaloneDeriving, . :

{-# LANGUAGE TypeFamilies, FlexibleContexts, GADTSyntax #-}

class (Show (Pig c), Show (Cow c)) => Configuration c where
    data Pig c
    data Cow c

data Farm c where
    Farm :: Configuration c => { pigs :: [Pig c],
                                 cows :: [Cow c] } -> Farm c deriving (Show)

, @hammar Configuration, Show, .

+1

All Articles