title: Overly abstract types in an interface
body: <p>I'm trying to learn Kotlin, but I find it quite a counter intuitive language.
  One big struggle is that Kotlin doesn't have any sort of general monad concept.  So I figured as a exercise to help me learn the language I would implement a monad <code>interface</code>, and maybe I'd be able to use it a little bit too.</p>
  <p>As an example here is a maybe we will be using:</p>
  <pre class="lang-kotlin prettyprint-override"><code>sealed class Maybe&lt;T&gt;
  class Nothing&lt;T&gt; : Maybe&lt;T&gt;()
  data class Just&lt;T&gt;(val getJust: T) : Maybe&lt;T&gt;()
  </code></pre>
  <p>So now to make some interfaces, we will fill in the functions later</p>
  <pre class="lang-kotlin prettyprint-override"><code>interface Functor&lt;T&gt;
  
  interface Applicative&lt;T&gt; : Functor&lt;T&gt;
  
  interface Monad&lt;T&gt; : Applicative&lt;T&gt;
  </code></pre>
  <p>Ok so I start with <code>Functor</code></p>
  <pre class="lang-kotlin prettyprint-override"><code>interface Functor&lt;T&gt; {
      fun &lt;K&gt; map(f: (T) -&gt; K): Functor&lt;K&gt;
  }
  </code></pre>
  <p>Now if we try and implement this we already have an issue, I want to enforce that <code>map</code> returns the same sort of functor it is a member to.  But all I can say is that it returns <em>some</em> thing that implements the <code>Functor&lt;K&gt;</code> interface.</p>
  <p>Now this isn't <em>that</em> bad since we can just ask anyone that implements the interface to use the same type for the return.  The interface is only useful this way so they will likely oblige.  However when we get to the <code>Applicative</code> things get real dicey.</p>
  <pre class="lang-kotlin prettyprint-override"><code>interface Applicative&lt;T&gt; : Functor&lt;T&gt; {
      fun &lt;K&gt; ap(m2: Applicative&lt;(T) -&gt; K&gt;): Applicative&lt;K&gt; 
  }
  </code></pre>
  <p>If I try to implement this for <code>Just</code> we have a problem (I'll skip over <code>Nothing</code> since it is a bit boring):</p>
  <pre class="lang-kotlin prettyprint-override"><code>data class Just&lt;T&gt;(val getJust: T) : Maybe&lt;T&gt;() {
      override fun &lt;K&gt; map(f: (T) -&gt; K): Just&lt;K&gt; {
          return Just(f(getJust))
      }
      override fun &lt;K&gt; ap(m2: Maybe&lt;(T) -&gt; K&gt;): Maybe&lt;K&gt; {
          return when (m2) {
              is Nothing&lt;(T) -&gt; K&gt; -&gt; Nothing()
              is Just&lt;(T) -&gt; K&gt; -&gt; {
                  Just(m2.getJust(getJust))
              }
          }
      }
  }
  </code></pre>
  <p>The compiler tells me that I didn't implement <code>ap</code> and <code>ap</code> overrides nothing.  What gives?  Well my <code>Applicative</code> interface actually requires that <code>ap</code> work on <em>any</em> <code>Applicative</code> not just the same one I am implementing for.  Apart from a few select applicative functors this is not possible.</p>
  <p>Is there some way I can have fix this interface so that it doesn't require taking an arbitrary <code>Applicative</code>?</p>