public
Last active

Failed attempt to get rid of boilerplate in methods using Numeric[T]

  • Download Gist
numeric-woes.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// Sorry Predef, we want '+' back!
import Predef.{any2stringadd => _, _}
 
object test {
{
trait MyNumeric[T] extends Ordering[T] {
def plus(x: T, y: T): T
//
// Made this implicit
//
implicit def fromInt(x: Int): T
class Ops(lhs: T) {
//
// Use view bounds here.
//
def +[TT <% T](rhs: TT) = plus(lhs, rhs)
}
implicit def mkNumericOps(lhs: T): Ops = new Ops(lhs)
}
object MyNumeric {
implicit val IntNumeric: Numeric[Int] = null
}
{
def foo1[T: MyNumeric](t: T): T = {
val nt = implicitly[MyNumeric[T]]; import nt._ // Ugly boiler plate!
t + 2
}
}
object MyNumericOps {
@inline implicit def ops[T](t: T)(implicit nt: MyNumeric[T]): MyNumeric[T]#Ops = nt.mkNumericOps(t)
implicit def tFromInt[T](t: Int)(implicit nt: MyNumeric[T]): T = nt.fromInt(t)
}
 
{
import MyNumericOps._
 
def foo2[T: MyNumeric](t: T): T = {
t + tFromInt(2) // this works
// compiler tries infers ops[T](t).+(2)(tFromInt[Nothing] _), and fails with: "could not find implicit value for parameter nt"
t + 2
0: T
}
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.