title: Why does Djinn fail to realize common monadic functions?
body: <p>I recently stumbled across <a href="https://hackage.haskell.org/package/djinn">Djinn</a> and was briefly playing around with it to try to see whether it would be useful in my everyday coding workflow. I was excited to see that Djinn had monads and tried to see whether it might be able to find some cool functions.</p>
  
  <p>Djinn did in fact work some wonders. The type signature of the initially (at least to me) unintuitive function <code>&gt;&gt;= (&gt;&gt;=)</code> is <code>Monad m =&gt; ((a -&gt; m b) -&gt; m a) -&gt; (a -&gt; m b) -&gt; m b</code>. Djinn was able to immediately demystify this by stating </p>
  
  <pre><code>Djinn&gt; f ? Monad m =&gt; ((a -&gt; m b) -&gt; m a) -&gt; (a -&gt; m b) -&gt; m b
  f :: (Monad m) =&gt; ((a -&gt; m b) -&gt; m a) -&gt; (a -&gt; m b) -&gt; m b
  f a b = a b &gt;&gt;= b
  </code></pre>
  
  <p>Unfortunately, Djinn can't seem to find other standard functions on monads, despite knowing about the Monad typeclass.</p>
  
  <ul>
  <li><p><code>join</code> (which should be <code>join = (&gt;&gt;= id)</code> or in Djinn's more verbose syntax <code>join a = a &gt;&gt;= (\x -&gt; x)</code>)</p>
  
  <pre><code>Djinn&gt; join ? Monad m =&gt; m (m a) -&gt; m a
  -- join cannot be realized.
  </code></pre></li>
  <li><p><code>liftM</code> (which should be <code>liftM f = (&gt;&gt;= (return . f))</code> or in Djinn's more verbose syntax <code>liftM a b = b &gt;&gt;= (\x -&gt; return (a x))</code>)</p>
  
  <pre><code>Djinn&gt; liftM ? Monad m =&gt; (a -&gt; b) -&gt; m a -&gt; m b
  -- liftM cannot be realized.
  </code></pre></li>
  <li><p>Even the basic <code>return :: Monad m =&gt; m a -&gt; m (m a)</code> cannot be found by Djinn or <code>return :: Monad m =&gt; (a, b) -&gt; m (a, b)</code>.</p>
  
  <pre><code>Djinn&gt; f ? Monad m =&gt; (a, b) -&gt; m (a, b)
  -- f cannot be realized.
  </code></pre></li>
  </ul>
  
  <p>Djinn knows how to use <code>\</code> to construct anonymous functions so why is this the case?</p>
  
  <p>My rough suspicion is that perhaps Djinn has a simplistic notion of typeclass and somehow treats <code>m a</code> as "fixed" so that <code>m (a, b)</code> is not seen as a case of <code>m a</code>, but I have no idea how to make that any more concrete than its current hand-wavy form or whether that intuition is correct.</p>