Uso de las bibliotecas estándar de haskell genéricos para los tipos de isomorfismos tipificados

Hay varias bibliotecas genéricas con numerosos módulos superpuestos solo en la plataforma Haskell (syb, Data.Typeable, Data.Data, GHC.Generics), pero estoy teniendo problemas con una tarea de programación genérica muy básica.

Quiero poder convertir entre tipos de la misma forma, es decir, quiero una función de conversión tipificada polimórfica entre los tipos isomorfos, esencialmente lo que se ofrece al final deeste papel(PDF) donde se mencionan las familias de tipos indexados.

No me preocupa deshacerme de mi plantilla, sino más bien poder construir nuevas bibliotecas en torno a sumas y abstracciones de productos.

La siguiente pregunta es en términos deGHC.Generic que pensé que era lo más cercano a lo que necesitaba, pero otras soluciones son bienvenidas.

Los siguientes dos tipos tienen la misma forma.

data Pair = Pair Char Int deriving (Generic, Show)
data Pair2 = Pair2 Char Int deriving (Generic, Show)

Quiero convertir valores entre ellos usando GHC.Generics. Lo siguiente no puede realizar la comprobación de tipos debido a todos los parámetros fantasmas y otras tonterías:

f :: Pair -> Pair2
f = to . from

En última instancia, quiero una función similar afromInteger que tiene un valor de retorno polimorfo para cualquierGeneric (o cualquier otra clase podría soportar esta) instancia. Supongo que estoy buscando algo comoGHC.Generics:

--class:
type family NormalForm a
class ToGeneric a where
    to :: a -> NormalForm a
class FromGeneric b where
    from :: NormalForm b -> b

--examples:
data A = A Char Int deriving Show
data B = B Char Int deriving Show

type instance NormalForm A = (Char,Int)
instance ToGeneric A where
    to (A a b) = (a,b)
instance FromGeneric A where
    from (a,b) = A a b

type instance NormalForm B = (Char,Int)
instance ToGeneric B where
    to (B a b) = (a,b)
instance FromGeneric B where
    from (a,b) = B a b

-- the function I'm looking for
coerce :: (ToGeneric a, FromGeneric b, NormalForm a ~ NormalForm b)=> a -> b
coerce = from . to

Con lo anterior podemos hacer todo lo que quiero:

*Main> (coerce $A 'a' 1) :: B
B 'a' 1
*Main> (coerce $A 'a' 1) :: A
A 'a' 1

EDITAR: Así es como Nathan Howell.f La función parece funcionar a continuación, en realidad.

Preguntas

¿Es posible hacer esto con las bibliotecas actualmente en la plataforma de haskell?

De no ser así, ¿podría definirse una biblioteca que aprovechara lasderiving mecanismo paraGeneric, Data, etc. sin recurrir a TH?

Respuestas a la pregunta(2)

Su respuesta a la pregunta