0
votes

I am trying put together a "registry" of Companion Objects - by storing them in a List which is bound using Generics.

An example is best:

trait Foo
case class A() extends Foo
object A
case class B() extends Foo
object B
case class C() extends Foo
object C


trait HasFoos {
  def allFoos: List[ _ <: Foo.type]
}
case class FooLookup() extends HasFoos { 
  def allFoos = List(A,B,C)
}

The error reported on FooLookup "def allFoos" is

  • type mismatch; found : A.type required: Foo.type

What does the HasFoos.allFoos need to look like, or alternatively, what does the List(A,B,C) need to look like.

I tried def allFoos: List[ _ <: Foo] as well; however it errors as well, and, I do want to work with the "Companion Object" not the class - I am sure I need some more generic's sugar dust around it but am not sure what it requires.

thanks in advance.

1
I would like to point out that wildcard here: def allFoos: List[ _ <: Foo.type] is unnecessary due to Scala's type variance. List in scala is covariant, which means you can type-safely assign, for example, List[String] to a variable of type List[Any] - something you could never do in Java.ghik

1 Answers

4
votes

So, as written, I can't get as far as defining the case class FooLookup, because I get an error "not found: value Foo" in defining the trait HasFoos.

To get HasFoos to compile as written, you must at some point have defined an object Foo, as well as the trait, no? If I do that, HasFoos will compile. But then "Foo.type" is the type of the singleton object Foo, not the type of companion objects of classes that extend the trait Foo.

A.type would be the type of object A. It would not be the type of things implementing a companion trait A, if one were defined.

I don't think that there is a type abstraction for what you want, something that automatically captures the description "Companion object of a type that implements Foo." I think you'll have to define such a type yourself:

 trait FooCompanion
 trait Foo
 case class A() extends Foo
 object A extends FooCompanion
 case class B() extends Foo
 object B extends FooCompanion
 case class C() extends Foo
 object C extends FooCompanion

 trait HasFoos {
   def allFoos: List[FooCompanion]
 }

 case class FooLookup() extends HasFoos { 
   def allFoos = List(A,B,C)
 }

Good luck!