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: kS
also helps. Is there any other construct?
X[_]
means X[Any]
. In particular your map does not relate the value types to the key types over the wild-carded argument to the Xode
type constructor. In addition in put
, scalac can widen the type of A
to Xode[Any]
if it needs to. Disclaimer: I'm not 100% sure about what I'm writing
The following rejects xtore.put(AXode(5))(Some("apples"))
and accepts xtore.put(AXode(5))(Some(0))
. Note that you also need to capture the type parameter of Xode
as opposed to the Xode[_]
version in the OP. I don't understand it completely and there might be a simpler solution.
def put[A,B[X] <: Xode[X]](k: B[A])(v: B[A]#S) {
m += k -> v
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.