title: type parameters and numeric widening
body: <p>As we know, we can add (subtract/multiply/etc.) two numbers of different <code>Numeric</code> types and the result will be the wider of the two types, regardless of their order.</p>
  
  <pre><code>33F + 9L  // Float + Long == Float
  33L + 9F  // Long + Float == Float
  </code></pre>
  
  <p>This is because each of the 7 <code>Numeric</code> classes (<code>Byte</code>, <code>Short</code>, <code>Char</code>, <code>Int</code>, <code>Long</code>, <code>Float</code>, <code>Double</code>) has 7 different <code>+()</code> methods (and <code>-()</code>, <code>*()</code>, etc), one for every <code>Numeric</code> type that can be received as a passed parameter. [There's an extra <code>+()</code> method for handling a <code>String</code> parameter, but that need not concern us here.]</p>
  
  <p>Now consider the following:</p>
  
  <pre><code>implicit class PlusOrMinus[T: Numeric](a: T) {
    import Numeric.Implicits._
    def +-(b: T) = if (util.Random.nextBoolean) a+b else a-b
  }
  </code></pre>
  
  <p>This works if the two operands are the same type, but it also works if the type of the 1st operand is wider than the type of the 2nd.</p>
  
  <pre><code>11F +- 2L  // result: Float = 9.0 or 13.0
  </code></pre>
  
  <p>I believe what's happening here is that the compiler uses <a href="http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#weak-conformance" rel="nofollow">weak conformance</a> to achieve <a href="http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-conversions" rel="nofollow">numeric widening</a> on the 2nd operand (the <code>b</code> parameter) as it is passed to the <code>+-()</code> method.</p>
  
  <p>But the 1st operand won't be widened to match the 2nd.  It won't even compile.</p>
  
  <pre><code>11L +- 2F  // Error: type mismatch; found: Float(2.0) required: Long
  </code></pre>
  
  <p>Is there any way around this limitatiion?</p>
  
  <p>I can't use a different type parameter for the <code>b</code> argument (<code>def +-[U: Numeric](b: U) = ...</code>) because a <code>Numeric</code>, expressed via a type parameter, can only add/subtract it's own type.</p>
  
  <p>Is the only solution to create 7 different classes (<code>PlusOrMinusShort/Int/Long/</code>etc.) with 7 different methods (<code>def +-(b:Short)</code>, <code>def +-(b:Int)</code>, <code>def +-(b:Long)</code>, etc.)?</p>