title: How to implement generic function in Scala with two argument types?
body: <p>I'd like to implement a function in Scala that computes the dot product of two numeric sequences as follows</p>
  
  <pre><code>val x = Seq(1,2,3.0)
  val y = Seq(4,5,6)
  val z = (for (a &lt;- x; b &lt;- y) yield a*b).sum
  scala&gt; z  : Double = 90.0
  
  val x = Seq(1,2,3)
  val y = Seq(4,5,6)
  val z = (for (a &lt;- x; b &lt;- y) yield a*b).sum
  scala&gt; z  : Int = 90
  </code></pre>
  
  <p>Notice that if the two sequences are of different types, the result is an Double.  If the two sequences are of the same type (e.g. Int), the result is an Int. </p>
  
  <p>I came up with two alternatives but neither meets the requirement as defined above.  </p>
  
  <p>Alternative #1:</p>
  
  <pre><code>def dotProduct[T: Numeric](x: Seq[T], y: Seq[T]): T = (for (a &lt;- x; b &lt;- y) yield implicitly[Numeric[T]].times(a, b)).sum
  </code></pre>
  
  <p>This returns the result in the same type as the input, but it can't take two different types.</p>
  
  <p>Alternative #2:</p>
  
  <pre><code>def dotProduct[A, B](x: Seq[A], y: Seq[B])(implicit nx: Numeric[A], ny: Numeric[B]) = (for (a &lt;- x; b &lt;- y) yield nx.toDouble(a)*ny.toDouble(b)).sum
  </code></pre>
  
  <p>This works for all numeric sequences.  However, it always return a Double, even if the two sequences are of the type Int.</p>
  
  <p>Any suggestion is greatly appreciated.</p>
  
  <p>p.s. The function I implemented above is not "dot product", but simply sum of product of two sequences.  Thanks Daniel for pointing it out.</p>
  
  <p>Alternative #3 (slightly better than alternatives #1 and #2):</p>
  
  <pre><code>def sumProduct[T, A &lt;% T, B &lt;% T](x: Seq[A], y: Seq[B])(implicit num: Numeric[T]) = (for (a &lt;- x; b &lt;- y) yield num.times(a,b)).sum
  
  sumProduct(Seq(1,2,3), Seq(4,5,6))  //&gt; res0: Int = 90
  sumProduct(Seq(1,2,3.0), Seq(4,5,6))  //&gt; res1: Double = 90.0
  sumProduct(Seq(1,2,3), Seq(4,5,6.0))  // Fails!!!
  </code></pre>
  
  <p>Unfortunately, the View Bound feature (e.g. "&lt;%") will be deprecated in Scala 2.10.</p>