title: Safe modelling of relational data in Haskell
body: <p>I find it very common to want to model relational data in my functional programs. For example, when developing a web-site I may want to have the following data structure to store info about my users:</p>
  
  <pre><code>data User = User 
    { name :: String
    , birthDate :: Date
    }
  </code></pre>
  
  <p>Next, I want to store data about the messages users post on my site:</p>
  
  <pre><code>data Message = Message
    { user :: User
    , timestamp :: Date
    , content :: String
    }
  </code></pre>
  
  <p>There are multiple problems associated with this data structure:</p>
  
  <ul>
  <li>We don't have any way of distinguishing users with similar names and birth dates.</li>
  <li>The user data will be duplicated on serialisation/deserialisation</li>
  <li>Comparing the users requires comparing their data which may be a costly operation.</li>
  <li>Updates to the fields of <code>User</code> are fragile -- you can forget to update all the occurences of <code>User</code> in your data structure.</li>
  </ul>
  
  <p>These problems are manageble while our data can be represented as a tree. For example, you can refactor like this:</p>
  
  <pre><code>data User = User
    { name :: String
    , birthDate :: Date
    , messages :: [(String, Date)] -- you get the idea
    }
  </code></pre>
  
  <p>However, it is possible to have your data shaped as a DAG (imagine any many-to-many relation), or even as a general graph (OK, maybe not). In this case, I tend to simulate the relational database by storing my data in <code>Map</code>s:</p>
  
  <pre><code>newtype Id a = Id Integer
  type Table a = Map (Id a) a
  </code></pre>
  
  <p>This kind of works, but is unsafe and ugly for multiple reasons:</p>
  
  <ul>
  <li>You are just an <code>Id</code> constructor call away from nonsensical lookups.</li>
  <li>On lookup you get <code>Maybe a</code>, but often the database structurally ensures that there is a value.</li>
  <li>It is clumsy.</li>
  <li>It is hard to ensure referential integrity of your data.</li>
  <li>Managing indices (which are very much necessary for performance) and ensuring their integrity is even harder and clumsier. </li>
  </ul>
  
  <p><strong>Is there existing work on overcoming these problems?</strong></p>
  
  <p>It looks like Template Haskell could solve them (as it usually does), but I would like not to reinvent the wheel.</p>