title: When would I want to use a Free Monad + Interpreter pattern?
body: <p>I'm working on a project that, amongst other things, involves a database access layer.  Pretty normal, really.  In a previous project, a collaborator encouraged me to use the Free Monads concept for a database layer and so I did.  Now I'm trying to decide in my new project what I gain.</p>
  
  <p>In the previous project, I had an API that looked rather like this.</p>
  
  <pre><code>saveDocument :: RawDocument -&gt; DBAction ()
  getDocuments :: DocumentFilter -&gt; DBAction [RawDocument]
  getDocumentStats :: DBAction [(DocId, DocumentStats)]
  </code></pre>
  
  <p>etc.  About twenty such public functions.  To support them, I had the <code>DBAction</code> data structure:</p>
  
  <pre><code>data DBAction a =
        SaveDocument          RawDocument         (DBAction a)
      | GetDocuments          DocumentFilter      ([RawDocument] -&gt; DBAction a)
      | GetDocumentStats                          ([(DocId, DocumentStats)] -&gt; DBAction a)
      | Return a
  </code></pre>
  
  <p>And then a monad implementation:</p>
  
  <pre><code>instance Monad DBAction where
      return = Return
      SaveDocument doc k &gt;&gt;= f = SaveDocument doc (k &gt;&gt;= f)
      GetDocuments df k &gt;&gt;= f = GetDocuments df (k &gt;=&gt; f)
  </code></pre>
  
  <p>And then the interpreter.  And then the primitive functions that implement each of the different queries.  Basically, I'm feeling that I had a huge amount of glue code.</p>
  
  <hr>
  
  <p>In my current project (in a totally different field), I have instead gone with a pretty ordinary monad for my database:</p>
  
  <pre><code>newtype DBM err a = DBM (ReaderT DB (EitherT err IO) a)
      deriving (Monad, MonadIO, MonadReader DB)
  
  indexImage :: (ImageId, UTCTime) -&gt; Exif -&gt; Thumbnail -&gt; DBM SaveError ()
  removeImage :: DB -&gt; ImageId -&gt; DBM DeleteError ()
  </code></pre>
  
  <p>And so on.  I figure that, ultimately, I'll have the "public" functions that represent high level concepts all running in the <code>DBM</code> context, and then I'll have the whole slew of functions that do the SQL/Haskell glue.  This is, overall, feeling much better than the free monad system because I'm not writing a huge amount of boilerplate code to gains me nothing but the ability to swap out my interpreter.</p>
  
  <p>Or...</p>
  
  <p>Do I actually gain something else with the Free Monad + Interpreter pattern?  If so, what?</p>