blue-sky
blue-sky

Reputation: 53906

Inferring/casting generic type to concrete type

When I attempt to compile :

package com

object typeparam extends App {

  new MyClass[Int]().f2(3)

  class MyClass[B] {

    def f2(b: B): B = {
      b + b
    }

  }

}

I receive compiler error

type mismatch;
[error]  found   : B
[error]  required: String
[error]       b + b
[error]           ^
[error] one error found

Why is b not inferred to an Int, as when I invoke the class I use the type parameter Int ?

If I instead use :

package com

object typeparam extends App {

  println(new MyClass[Int]().f2(3) * 3)

  class MyClass[B] {

    def f2(b: B): B = {
      b
    }

  }

}

The value 9 is correctly printed. So it seems the Int type is correctly inferred.

Is this related to type erasure ?

Upvotes: 1

Views: 137

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

It doesn't have anything to do with type erasure. Your type parameter B is unbounded, and not every type has a + method. But every type can be implicitly converted to String in order to use the + method (inferred as Any), and that's exactly what's happening here.

Perhaps require the Numeric trait if you want this to only work with numbers?

class MyClass[B](implicit num: Numeric[B]) {
   def f2(b: B): B = num.plus(b, b)
}

scala> def myInst = new MyClass[Int]
myInst: MyClass[Int]

scala> myInst.f2(3)
res0: Int = 6

Upvotes: 3

Related Questions