I made a TH function earlier this year to produce types for constructors:
data Foo = LeftFoo !Int | RightFoo !Char
deriving Show
$(constructorType 'LeftFoo)
deriving instance Show LeftFooC
In a repl you can see it generates a type with a single constructor, an introducer, and an eliminator.
*Main> :browse
type Foo :: *
data Foo = LeftFoo !Int | RightFoo !Char
type LeftFooC :: *
data LeftFooC = LeftFooC Int
introLeftFooC :: Foo -> Maybe LeftFooC
elimLeftFooC :: LeftFooC -> Foo
*Main> introLeftFooC (RightFoo 'a')
Nothing
*Main> introLeftFooC (LeftFoo 123)
Just (LeftFooC 123)
*Main> elimLeftFooC $ LeftFooC 456
LeftFoo 456