Reputation: 113
I'd like to have a method like this:
def foo[O] = O(1,2,3)
Where "O" would be a scala object with a defined apply method. With my signature, I got the "Cannot resolve symbol O" error.
Calling foo passing a "Set" or a "List" as parameter gives me the "Type XXX takes type parameter". What's the way to pass a companion object as a parametric type?
How can I create this method?
Upvotes: 2
Views: 1552
Reputation: 2327
Pass the apply method (the thing that is called when you say List(1, 2, 3)
) as an argument instead:
def foo[O](apply: (Int*) => O): O = apply(1, 2, 3)
println(foo(List.apply))
->
List(1, 2, 3)
Or, if you really want to pass in the companion object of a Collection class (though this is less versatile than the above solution), you can pass in GenericCompanion
objects such as the List
companion:
def foo[O[T] <: GenTraversable[T]](comp: GenericCompanion[O]): O[Int] = comp(1, 2, 3)
println(foo(List))
->
List(1, 2, 3)
Note that this requires higher-kinded types to be enabled in the compiler.
Or, rather than passing in the companion object, you can use an implicit CanBuildFrom (these are defined for you for all collections):
def foo[O[_]](implicit bf: CanBuildFrom[O[_], Int, O[_]]): O[Int] =
bf().++=(Seq(1, 2, 3)).result().asInstanceOf[O[Int]]
println(foo[List])
->
List(1, 2, 3)
Upvotes: 5
Reputation: 696
The type of a companion object is referenced using the .type
property. If you want to create a list of companion objects, the following would work:
object MyObject {
def apply():Unit = {
println("Hello, world")
}
}
val c = List[MyObject.type](MyObject, MyObject)
c.foreach(_.apply())
Upvotes: -1