title: How can I use HaskellDB with polymorphic fields? (Problems with overlapping instances)
body: <p>I have a schema which has 6 different types of entities, but they all have a lot of things in common. I figured I could probably abstract a lot of this commonality out at the type level, but I've hit a problem with HaskellDB and overlapping instances. Here's the code I started with, which works fine:</p>
  
  <pre><code>import Database.HaskellDB
  import Database.HaskellDB.DBLayout
  
  data Revision a = Revision deriving Eq
  data Book = Book
  
  instance FieldTag (Revision a) where
    fieldName _ = "rev_id"
  
  revIdField :: Attr (Revision Book) (Revision Book)
  revIdField = mkAttr undefined
  
  branch :: Table (RecCons (Revision Book) (Expr (Revision Book)) RecNil)
  branch = baseTable "branch" $ hdbMakeEntry undefined
  bookRevision :: Table (RecCons (Revision Book) (Expr (Revision Book)) RecNil)
  bookRevision = baseTable "book_revision" $ hdbMakeEntry undefined
  
  masterHead :: Query (Rel (RecCons (Revision Book) (Expr (Revision Book)) RecNil))
  masterHead = do
    revisions &lt;- table bookRevision
    branches &lt;- table branch
    restrict $ revisions ! revIdField .==. branches ! revIdField
    return revisions
  </code></pre>
  
  <p>This works fine, but <code>branch</code> is too specific. What I actually want to express is the following:</p>
  
  <pre><code>branch :: Table (RecCons (Revision entity) (Expr (Revision entity)) RecNil)
  branch = baseTable "branch" $ hdbMakeEntry undefined
  </code></pre>
  
  <p>However, with this change, I get the following error:</p>
  
  <pre><code>Overlapping instances for HasField
                              (Revision Book)
                              (RecCons (Revision entity0) (Expr (Revision entity0)) RecNil)
    arising from a use of `!'
  Matching instances:
    instance [overlap ok] HasField f r =&gt; HasField f (RecCons g a r)
      -- Defined in Database.HaskellDB.HDBRec
    instance [overlap ok] HasField f (RecCons f a r)
      -- Defined in Database.HaskellDB.HDBRec
  (The choice depends on the instantiation of `entity0'
   To pick the first instance above, use -XIncoherentInstances
   when compiling the other instance declarations)
  In the second argument of `(.==.)', namely `branches ! revIdField'
  In the second argument of `($)', namely
    `revisions ! revIdField .==. branches ! revIdField'
  In a stmt of a 'do' expression:
        restrict $ revisions ! revIdField .==. branches ! revIdField
  </code></pre>
  
  <p>I've tried blindly throwing <code>-XOverlappingInstances</code> and <code>-XIncoherentInstances</code> at this, but that doesn't help (and I'd like to actually understand why replacing a concrete type with a type variable causes this to be so problematic).</p>
  
  <p>Any help and advice would be much appreciated!</p>