2

As also seen in the scaladoc, sets are invariant :( So what do you do when you wish treat one as if it were covariant?

I have a constructor object:

object SimpleGraph {
  def apply[ID](vertices: List[AbstractVertex[ID]], edges: Set[AbstractEdge[ID]]) = {
    val simpleGraph = new SimpleGraph[ID, AbstractVertex[ID], AbstractEdge[ID]]
    vertices.map(simpleGraph.addNode)
    edges.map(simpleGraph.addEdge)
    simpleGraph
  }   
}

Given the invariance, sets of types that adhere to T <: AbstractEdge[ID] won't make it through into my apply function. The compilation error suggests using a wildcard type, which as much as I fathom means circumventing type safety altogether (?). My own solution is ugly because it uses cpu cycles and more memory to get over the invariance: changing the prototype's type from Set to List and converting back and forth between a list and a set to get the data through.

Have you got a better suggestion?

Thanks!

Community
  • 1
  • 1
matanster
  • 15,072
  • 19
  • 88
  • 167
  • I think we should have a `CovariantSet` type in scala 3.0 that will also need to drop Set's `apply` convenience method, to allow that :) – matanster Sep 24 '15 at 19:11

1 Answers1

2

I am not terribly sure about it, because I am currently not able to test it properly, But wouldn't it work to tell your apply the exact type of the items in the set by type parameter?

object SimpleGraph {
  def apply[ID, EDGE <: AbstractEdge[ID]](vertices: List[AbstractVertex[ID]], edges: Set[EDGE]) = {
    val simpleGraph = new SimpleGraph[ID, AbstractVertex[ID], AbstractEdge[ID]]
    vertices.foreach(simpleGraph.addNode)
    edges.foreach(simpleGraph.addEdge)
    simpleGraph
  }
}
Sascha Kolberg
  • 7,092
  • 1
  • 31
  • 37
  • brilliant! I guess the extra type parameter avoids the variance check on the `edges` parameter, making this work. Great pattern! – matanster Sep 24 '15 at 19:23
  • It does at the same time pass the burden to the caller to this apply, as the compiler won't deduce the type parameter but require it stated there. I still wish Scala 3 will rid us of this thorny aspect. – matanster Sep 24 '15 at 19:24