Использование стандартных универсальных библиотек haskell для типизированных изоморфизмов типов

В одной только платформе Haskell есть несколько универсальных библиотек с множеством перекрывающихся модулей (syb, Data.Typeable, Data.Data, GHC.Generics), но у меня возникли проблемы с очень простой задачей общего программирования.

Я хочу иметь возможность конвертировать между типами одной и той же формы, т.е. я хочу полиморфную, типизированную функцию преобразования между изоморфными типами, по сути, то, что предлагается в концеЭта бумага(PDF), где упоминаются семейства индексированных типов.

Я не озабочен тем, чтобы сломать мой шаблон, а скорее имею возможность создавать новые библиотеки на основе абстракций суммы и продукта.

Вопрос ниже в терминахGHC.Generic который я думал, был ближе всего к тому, что мне нужно, но другие решения приветствуются.

Следующие два типа имеют одинаковую форму

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

Я хочу конвертировать значения между ними, используя GHC.Generics. Следующее не может проверить тип из-за всех параметров фантома и другой ерунды:

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

В конечном счете, я хочу функцию, похожую наfromInteger который имеет полиморфное возвращаемое значение для любогоGeneric (или любой другой класс может поддерживать это) экземпляр. Я думаю, что я ищу что-то вродеGHC.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

С вышеизложенным мы можем делать все, что я хочу:

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

EDIT: Вот как Натан Хауэллf функция, кажется, работает ниже, на самом деле.

Questions

Is this possible to do with libraries currently in the haskell platform?

If not, could a library be defined that leveraged the existing deriving mechanism for Generic, Data, etc. without resorting to TH?

Ответы на вопрос(2)

Ваш ответ на вопрос