Ambiguous Actions with Virtual Types and Numeric

Welcome to Scala version 2.10.2 (Java HotSpot 64-Bit Server VM, Java 1.7.0_15). scala> :paste // Entering paste mode (ctrl-D to finish) trait Reduce { type X; def add(x:X) } 

Now I declare a Foo class that can be populated using Reducer or chain alone.

 class Foo[A](val a:A) { def fill(r: Reduce { type X = A}) = {r.add(a)} def chain[R >:A](r: Reduce { type X = R }) = { r.add(a); new Foo(r)} } 

Now I create a class that is a reducer for some number type Y

 class AsInt[Y: Numeric] extends Reduce { type X = Y var i = 0 override def add(y:Y) = {i = implicitly[Numeric[Y]].toInt(y)} } 

And I finished

 // Exiting paste mode, now interpreting. defined trait Reduce defined class Foo defined class AsInt 

Now I can create and populate an instance of Foo :

 scala> val fL = new Foo(123L) fL: Foo[Long] = Foo@12979ef0 scala> fL.fill(new AsInt) 

So far so good. Now I bind one:

 scala> fL.chain(new AsInt) <console>:12: error: ambiguous implicit values: both object BigIntIsIntegral in object Numeric of type scala.math.Numeric.BigIntIsIntegral.type and object IntIsIntegral in object Numeric of type scala.math.Numeric.IntIsIntegral.type match expected type Numeric[Y] fL.chain(new AsInt) ^ 

Now i'm stuck. Tipper should look for some type of R >: Long , for which there is an implicit Numeric[R] in the region. How can it be possible for Numeric[Int] or Numeric[BigInt] match an account?

The typeter seems to have no problem solving it:

 scala> def foo[Z >: Long](implicit N: Numeric[Z]) = println(N) foo: [Z >: Long](implicit N: Numeric[Z])Unit scala> foo scala.math.Numeric$LongIsIntegral$@67236f24 

What am I missing?

+4
source share

Source: https://habr.com/ru/post/1500294/


All Articles