I have the following definitions:
trait Xode[+R] {
type S = Option[R]
}
case class AXode(a: Int) extends Xode[Int]
case class BXode(b: String) extends Xode[String]
object xtore {
private var m: Map[Xode[_], Xode[_]#S] = Map()
def put[A <: Xode[_]](k: A)(v: A#S) {
m += k -> v
}
}
When executing the following, no error is raised, although I expect AXode#S to be Option[Int].
xtore.put(AXode(5))(Some("apples")) // <-- no error
What might happen is that A
is inferred to be Xode[_]
, and then Xode[_]#S
gets to be Option[_]
. Could I express my intention with type parameters?
When implemented with R being an abstract type member instead of a type parameter, it works as expected. Or dependent method types and typing v: k.S
also helps. Is there any other construct?
X[_]
meansX[Any]
. In particular your map does not relate the value types to the key types over the wild-carded argument to theXode
type constructor. In addition input
, scalac can widen the type ofA
toXode[Any]
if it needs to. Disclaimer: I'm not 100% sure about what I'm writing ;) – ziggystarMap
(its type can't express what I want, that's why I hide it), but would likeput
to behave correctly. – ron