title: OCaml: higher kinded polymorphism (abstracting over modules?)
body: <p>Let's say I have a list of options:</p>
  
  <pre><code>let opts = [Some 1; None; Some 4]
  </code></pre>
  
  <p>I'd like to convert these into an option of list, such that:</p>
  
  <ul>
  <li>If the list contains <code>None</code>, the result is <code>None</code></li>
  <li>Otherwise, the various ints are collected.</li>
  </ul>
  
  <p>It's relatively straightforward to write this for this specific case (using <a href="https://github.com/janestreet/core/blob/master/lib" rel="noreferrer">Core</a> and the <code>Monad</code> module):</p>
  
  <pre><code>let sequence foo =
  let open Option in
  let open Monad_infix in
    List.fold ~init:(return []) ~f:(fun acc x -&gt;  
      acc &gt;&gt;= fun acc' -&gt; 
      x &gt;&gt;= fun x' -&gt; 
      return (x' :: acc')
      ) foo;;
  </code></pre>
  
  <p>However, as the question title suggests, I'd really like to abstract over the type constructor rather than specialising to <code>Option</code>. Core seems to use a functor to give the effect of a higher kinded type, but I'm not clear how I can write the function to be abstracted over the module. In Scala, I'd use an implicit context bound to require the availability of some <code>Monad[M[_]]</code>. I'm expecting that there's no way of implicitly passing in the module, but how would I do it explicitly? In other words, can I write something approximating this:</p>
  
  <pre><code>let sequence (module M : Monad.S) foo =
  let open M in
  let open M.Monad_infix in
    List.fold ~init:(return []) ~f:(fun acc x -&gt;  
      acc &gt;&gt;= fun acc' -&gt; 
      x &gt;&gt;= fun x' -&gt; 
      return (x' :: acc')
      ) foo;;
  </code></pre>
  
  <p>Is this something that can be done with first class modules?</p>
  
  <p>Edit: Okay, so it didn't actually occur to me to try using that specific code, and it appears it's closer to working than I'd anticipated! Seems the syntax is in fact valid, but I get this result:</p>
  
  <pre><code>Error: This expression has type 'a M.t but an expression was expected of type 'a M.t
  The type constructor M.t would escape its scope    
  </code></pre>
  
  <p>The first part of the error seems confusing, since they match, so I'm guessing the problem is with the second - Is the problem here that the return type doesn't seem to be determined?  I suppose it's dependent on the module which is passed in - is this a problem? Is there a way to fix this implementation?</p>