1

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 Answers 2

4

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
Sign up to request clarification or add additional context in comments.

2 Comments

Although this is a good solution, I've stated that I don't want trait type parameters, I would like the T type in the function to be inferred. Trait abstract types in simple cases like this work like normal class type parameters...
Well with a little workaround I've managed to get what I wanted thanks to your answer, I'm gonna accept it...
1

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)

4 Comments

Didn't know about -Yinfer-argument-types, thanks! Unfortunately give the type parameter when I instantiate the trait is exactly what I would like to avoid, considering that I would like the client to implement the function without giving type parameter (and then use view bounds for variance/contravariance). It's starting to seem to me too much for Scala type inference...
@VincenzoMaggio Specialization is what you intend. My question, What do you do if it's not the type you expect, has the answer: invoke the other method. At least, specialization is the only way I've made sense of your question.
Isn't specialization just for primitive types?!
@VincenzoMaggio Yes, I was conceptualizing. You could do the dispatch yourself, either dynamically or with a macro, from f[A: TypeTag](a: A) to whatever implementation is available.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.