Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The problem can be solved in different ways. For example, if you just want type <code>T</code> to have some method (and you don't care whether this method defined on the object or there is implicit conversion that coverts object to something that has this method), then you can use <em>view bounds</em>. Here is an example that expects type <code>T</code> to have method <code>def *(times: Int): T</code>:</p> <pre><code>class Table[T &lt;% {def *(times: Int): T}](bla: Array[T]) { bla.foreach( x =&gt; println(x * 2)) } new Table(Array("Hello", "World")) // Prints: // HelloHello // WorldWorld </code></pre> <p><code>String</code> does not have method <code>*</code>, but there exist an implicit conversion to <a href="http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/immutable/StringOps.html" rel="nofollow">StringOps</a> that has this method.</p> <p>Here is another example. In this case I restricting type <code>T</code> with method <code>def size: Int</code>:</p> <pre><code>class Table[T &lt;% {def size: Int}](bla: Array[T]) { bla.foreach( x =&gt; println(x.size)) } new Table(Array(List(1, 2, 3), List("World"))) // Prints: // 3 // 1 </code></pre> <p><code>List</code> has method <code>size</code>, and it also works as expected.</p> <p>But this could be more involving if you are working with numeric values like ints, floats, doubles, etc. In this case I can recommend you to use <em>context bound</em>. Scala has <a href="http://www.scala-lang.org/api/current/scala/math/Numeric.html" rel="nofollow">Numeric</a> type class. You can use it to work with numbers without knowledge about their type (with <code>Numeric</code> you can actually work with anything that can be represented as number, so your code would be much more general and abstract). Here is an example if it:</p> <pre><code>import math.Numeric.Implicits._ class Table[T : Numeric](bla: Array[T]) { bla.foreach( x =&gt; println(x * x)) } new Table(Array(1, 2, 3)) // Prints: // 1 // 4 // 9 new Table(Array(BigInt("13473264523654723574623"), BigInt("5786785634377457457465784685683746583454545454"))) // Prints: // 181528856924372945350108280958825119049592129 // 33486887978237312740760811863500355048015109407078304275771413678604907671187978933752066116 </code></pre> <hr> <h3>Update</h3> <p>As you noted in comments, <code>Numeric</code> still does not solve your problem, because it can only work on the numbers of the same type. You can simply solve this problem by introducing new type class. Here is an example of it:</p> <pre><code>import math.Numeric.Implicits._ trait Convert[From, To] { def convert(f: From): To } object Convert { implicit object DoubleToInt extends Convert[Double, Int] { def convert(d: Double): Int = d.toInt } implicit object DoubleToBigInt extends Convert[Double, BigInt] { def convert(d: Double): BigInt = d.toLong } } type DoubleConvert[To] = Convert[Double, To] class Table[T : Numeric : DoubleConvert](bla: Array[T]) { bla.foreach( x =&gt; println(x * implicitly[DoubleConvert[T]].convert(probability(x)))) def probability(t: T) : Double = t.toDouble + 2.5 } new Table(Array(1, 2, 3)) new Table(Array(BigInt("13473264523654723574623"), BigInt("5786785634377453434"))) </code></pre> <p>With <code>DoubleConvert</code> type class and <code>T : Numeric : DoubleConvert</code> context bound you are not only saying, that <code>T</code> should be some kind of number, but also that there should exist some evidence, that it can be converted from <code>Double</code>. You are receiving such evidence with <code>implicitly[DoubleConvert[T]]</code> and then you are using it to convert <code>Double</code> to <code>T</code>. I defined <code>Convert</code> for Double -> Int and Double -> BigInt, but you can also define you own for the types you need.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload