You can do this, although you still need a datastructure that allows you to use the contained type:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Tutorial where
data Gender = Male | Female deriving (Show)
data Race = White | Black deriving (Show)
type Age = Int
data Answer a where
Answer :: RacistAgistSexist a => a -> Answer a
deriving instance Show w => Show (Answer w)
data GenderRaceAge
= Gender Gender
| Race Race
| Age Age
class RacistAgistSexist a where
genderRaceAge :: a -> GenderRaceAge
instance RacistAgistSexist Gender where
genderRaceAge = Gender
instance RacistAgistSexist Race where
genderRaceAge = Race
instance RacistAgistSexist Age where
genderRaceAge = Age
-- You can use genderRaceAge to get a GenderRaceAge out of the contained type if you don't know 'a'