
I'd like to know how to conveniently generate specialisations of a product type without resorting to Template Haskell. Concretely, I have a type like data MyProduct a b c = MyProduct { foo :: a , bar :: b , baz :: c } and I use it in type signatures in various different specialisations. Generally the "base" type of each component stays fixed but it is wrapped in zero or more type constructors. For example a. MyProduct Int Bool String b. MyProduct (Maybe Int) (Maybe Bool) (Maybe String) c. MyProduct [IO Int] [IO Bool] [IO String] d. MyProduct (P Int) (P Bool) (P String) for various P that are not always functors in my uses. I thought I might be able to reduce this duplication by parametrisation, that is data MyProduct f a b c = MyProduct { foo :: f a , bar :: f b , baz :: f c } However, I can't always substitute a type constructor for `f` because that doesn't work for cases a. or c.. I thought a type family might work but it seems they have to be fully applied, like type synonyms. Is there an approach to this problem that will allow me to avoid Template Haskell here? Thanks, Tom