Scala error implementing abstract method with type parameter

534 views Asked by At

to make it short, this works:

object Main {
  def main(args: Array[String]) {
    trait T1[T] {
      def f1(a: T): Double
    }

    val ea1 = new T1[List[String]] {
      def f1(a: List[String]): Double = a.length
    }
  }
}

But this won't compile:

object Main {
  def main(args: Array[String]) {
    trait T1 {
      def f1[T](a: T): Double
    }

    val ea1 = new T1 {
      def f1(a: List[String]): Double = a.length
    }
  }
}

object creation impossible, since method f1 in trait T1 of type [T](a: T)Double is not defined
    val ea1 = new T1 {
              ^

It seems like the method is not taken into account because of type parameter on method.

How can I achieve this without using trait type parameters or trait abstract types?! TIA!

2

There are 2 answers

2
Shrey On BEST ANSWER

You may want to define a type T to do away with Trait Type Parameters and accomplish the same as..

    trait T1 {
      type T
      def f1(a: T): Double
    }

    val ea1 = new T1 {
       type T = List[String]
       def f1(a: T): Double = a.length
    }                                            

    ea1.f1(List("1","2"))  
    // res0: Double = 2.0
4
som-snytt On

There is a "private option" -Yinfer-argument-types that lets you:

scala> trait T { def f(i: Int) }
defined trait T

scala> new T { def f(i) = 2 * i }
res1: T = $anon$1@7915e83

You're asking for an option that would do the equivalent of:

scala> new T { def f() = 2 * i }

except with type parameters instead of value parameters.

I'm not sure what the semantics would be in your example. The method has a type param, but throw if it's not the type I expect?

Edit: Maybe you mean this:

scala> trait T { def f[ @specialized(Int) A](a: A): A = ??? }
defined trait T

scala> new T { def f(i: Int) = 2*i }
res0: T{def f(i: Int): Int} = $anon$1@50844aeb

scala> res7 f 7
warning: there were 1 feature warning(s); re-run with -feature for details
res8: Int = 14

There is no type param on the specialized method.

Update: This is probably the first appearance of elided REPL stack traces on SO:

scala> res7 f "hi!"
warning: there were 1 feature warning(s); re-run with -feature for details
scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:229)
  at $anon$1.f(<console>:9)