title: Using standard haskell generics libraries for typed type-isomorphisms
body: <p>There are several generics libraries with numerous overlapping modules in just the Haskell Platform alone (<code>syb</code>, <code>Data.Typeable</code>, <code>Data.Data</code>, <code>GHC.Generics</code>), but I'm having trouble with a very basic generic programming task.</p>
  
  <p>I want to be able to convert between types of the same shape, i.e. I want a polymorphic, typed conversion function between isomorphic types, essentially what is offered at the end of <a href="http://igitur-archive.library.uu.nl/math/2007-0404-200310/jeuring_04_inferringtype.pdf" rel="noreferrer">this paper</a>(PDF) where indexed type families are mentioned. </p>
  
  <p>I'm not concerned with scrapping my boilerplate, but rather with being able to build new libraries around sum and product abstractions.</p>
  
  <p>The question below is in terms of <code>GHC.Generic</code> which I thought was closest to what I needed, but other solutions are welcome.</p>
  
  <hr>
  
  <p>The following two types have the same shape</p>
  
  <pre><code>data Pair = Pair Char Int deriving (Generic, Show)
  data Pair2 = Pair2 Char Int deriving (Generic, Show)
  </code></pre>
  
  <p>I want to convert values between them using GHC.Generics. The following fails to typecheck because of all the phantom parameters and other nonsense:</p>
  
  <pre><code>f :: Pair -&gt; Pair2
  f = to . from
  </code></pre>
  
  <p>Ultimately I want a function akin to <code>fromInteger</code> that has a polymorphic return value for any <code>Generic</code> (or whatever other class could support this) instance. I guess I'm looking for something like <code>GHC.Generics</code>:</p>
  
  <pre><code>--class:
  type family NormalForm a
  class ToGeneric a where
      to :: a -&gt; NormalForm a
  class FromGeneric b where
      from :: NormalForm b -&gt; 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)=&gt; a -&gt; b
  coerce = from . to
  </code></pre>
  
  <p>With the above we can do everything I want:</p>
  
  <pre><code>*Main&gt; (coerce $A 'a' 1) :: B
  B 'a' 1
  *Main&gt; (coerce $A 'a' 1) :: A
  A 'a' 1
  </code></pre>
  
  <p><strong>EDIT:</strong> This is how Nathan Howell's <code>f</code> function seems to work below, actually.</p>
  
  <h3>Questions</h3>
  
  <ol>
  <li><p>Is this possible to do with libraries currently in the haskell platform? </p></li>
  <li><p>If not, could a library be defined that leveraged the existing <code>deriving</code> mechanism for <code>Generic</code>, <code>Data</code>, etc. without resorting to TH?</p></li>
  </ol>