title: In scala, what is the easiest way to chain functions defined with a type class and of which output type depends on it?
body: <p>Assuming that a class <code>Thing</code> is defined, and an operation <code>+</code> is associated with a type class:</p>
  
  <pre><code>  trait TypeClass[X, Y] {
  
      type Out
      def v: Out
    }
  
    object TypeClass {
  
      implicit def summon[X &lt;: Int, Y &lt;: Int]: TypeClass[X, Y] = new TypeClass[X, Y] {
  
        type Out = Int
  
        override def v: Out = 2
      }
    }
  
    case class Thing[X]() {
  
      def +[Y](that: Thing[Y])(implicit typeClass: TypeClass[X, Y]): typeClass.Out = typeClass.v
    }
  </code></pre>
  
  <p>Now if I want to define a shortcut function <code>+2x</code>, which represents <code>X + Y + Y</code>. My first instinct was to introduce an implicit parameter:</p>
  
  <pre><code>    def ++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out &lt;: Z }, t2: TypeClass[Z, Y]): t2.Out = t2.v
  </code></pre>
  
  <p>But then t2 becomes an impossible shoe to fill:</p>
  
  <pre><code>
      assert(Thing(1) + Thing(2) == Thing(2)) // works fine
  
      assert(Thing(1) ++ Thing(2) == Thing(2)) // TypeClass.scala:34: could not find implicit value for parameter t2: TypeClass.this.TypeClass[Z,Int]
  </code></pre>
  
  <p>I could also use a more intuitive format:</p>
  
  <pre><code>
      def +++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out &lt;: Y }, a: Any = this + that + that): a.type =
        a
  </code></pre>
  
  <p>unfortunately implicit t1 cannot be made visible to the expression that defines the result:</p>
  
  <pre><code>TypeClass.scala:29: type mismatch;
   found   : a.type (with underlying type Any)
   required: AnyRef
  </code></pre>
  
  <p>so what is the easiest, most intuitive way to define this?</p>
  
  <p>Thanks a lot for your opinion</p>