Iterating through a list of companion objects

I have stored some parameters in the companion objects of several classes, and I would like to be able to check and print those parameters for each companion object. In each companion object, I have defined a function called checkParameters, and I would like to iterate through such a list of companion objects and call that function for each one. But if I put them in a List (or Vector, or Set), the List type reverts to something that does not support the function call. Is there a way to do this? I could put them into a Tuple, but what should the type of the Tuple be, and how can I make it general enough for an arbitrary number of companion objects? I prefer to stick with the standard Scala library. Any ideas? Thanks.

Maybe you could define a trait that defines checkParameters, and mix it into each object, then use a List of objects of the trait?

3 Likes

Yes, that works. Thanks.

I was thinking that perhaps a structural type might work and be less intrusive, but I could not figure out the syntax.

Yeah, in Haskell, I would use a typeclass. Unfortunately, Scala typeclasses have so much overhead, a trait seems like a better alternative since you just need to enforce that all your objects provide the “checkParameters” method.

Structural types are great but they include runtime overhead and are not the easyest solution to work with. In general I prefer typeclasses or interfaces.

After a bit of troubles anyhow I’ve managed to make up an example with structural types.


  object A {
    def checkParameters: Int = 0
  }

  object B {
    def checkParameters: Int = 1
  }

  object C {
    def checkParameters: Int = 2
  }

  import scala.language.reflectiveCalls

  type ST = {def checkParameters: Int}

  def iterate(listObjects: List[ST]): Unit =
    listObjects.foreach(o => println(o.checkParameters))

  val a: ST =  A
  val b: ST =  B
  val c: ST =  C

  val l: List[ST] = List(a, b, c)

  iterate(l)

prints

0
1
2

The shorter version

List[{ def checkParameters: Int }](A, B, C).foreach(o => println(o.checkParameters))

also works. However I don’t really see any benefit in doing this. If you define this method in a companion object, it’s just as easy to also have that object extend a trait.