Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to instantiate trait

Tags:

scala

I try to define a simple trait like this:

scala> trait T { def p[A,B]: Map[A,B] }
defined trait T

scala> new T { def p = Map(0 -> 1) }
<console>:7: error: object creation impossible, since method p in trait T of type [A,B]Map[A,B] is not defined
       new T { def p = Map(0 -> 1) }
       ^

How come?

Thanks

like image 592
Levi Greenspan Avatar asked Jan 22 '26 00:01

Levi Greenspan


2 Answers

You can have a generic method, but the implementation of an abstract generic method must itself be generic:

scala> trait T { def p[A,B]: Map[A,B] }
defined trait T

scala> new T { def p[S, T] = Map[S, T]() }
res13: java.lang.Object with T = $anon$1@1f74864

Remember that unbounded type parameters are universally quantified. You're saying p is defined for all pairs of types without exception or constraint. Many S and T bindings are incompatible with Int, so you cannot just return a Map[Int, Int] where a Map[S, T] is required.

Update: Re: "So I can have non-generic implementations of generic abstract classes and traits but not of generic methods?"

You can have non-generic implementation of generic abstract classes in this sense:

abstract class C[A, B, C] { /* ... */ }
class D extends C[Int, String, Boolean] { /* ... */ }

Or like this:

class E extends C { /* ... */ }

Though that one's the same as:

class E extends C[Nothing, Nothing, Nothing] { /* ... */ }

And Nothing is an uninhabited type in Scala.

But you cannot implement an abstract generic method with a non-generic method

like image 66
Randall Schulz Avatar answered Jan 26 '26 12:01

Randall Schulz


I assume you want to do this:

scala> trait T[A,B] { def p: Map[A,B] }
defined trait T

scala> new T[Int,Int] { def p = Map(0 -> 1) }
res0: java.lang.Object with T[Int,Int] = $anon$1@2f1261b1
like image 26
Viktor Klang Avatar answered Jan 26 '26 12:01

Viktor Klang