Texas
Texas

Reputation: 156

Scala type mismatch error trying to view parameterised or abstract type constructor as its upper bound

Stripped down example:

trait WithUpperBounds[AA[_] <: Set[_], Node, Edge] {
    val nodes: AA[Node]
    val edges: AA[Edge]
}

class WithoutUpperBounds[AA[_] <: Set[_], Node, Edge](
    val nodes: AA[Node],
    val edges: AA[Edge]
) extends WithUpperBounds[AA, Node, Edge] {
    val nodes2Set: Set[Node] = nodes
    val edges2Set: Set[Edge] = edges
}

REPL output:

scala> :l …/Sandbox.scala
Loading …/Sandbox.scala...
defined trait WithUpperBounds
<console>:10: error: type mismatch;
 found   : AA[Node]
 required: Set[Node]
        val nodes2Set: Set[Node] = nodes
                                   ^
<console>:11: error: type mismatch;
 found   : AA[Edge]
 required: Set[Edge]
        val edges2Set: Set[Edge] = edges
                                   ^

Higher-order functions especially for comprehensions compound my issue.

Upvotes: 0

Views: 298

Answers (2)

Texas
Texas

Reputation: 156

@thoredge pointed me in the right direction. I found the solution in Predef.scala:

type Set[A] = collection.immutable.Set[A]

Wildcards throws away type equivalence but you can instead abstract over any arbitrary parameter without declaring it. My trait now looks like:

trait WithUpperBounds[AA[B] <: Set[B], Node, Edge]…

Upvotes: 0

thoredge
thoredge

Reputation: 12601

Change the wildcard in the Seq[_] description to this:

class WithoutUpperBounds[AA[_] <: Seq[_ <: Node], B <: Node](val nodeSeq: AA[B]) extends WithUpperBounds[AA, B] {

Upvotes: 1

Related Questions