RHS 上的模式活页夹变量类型与 LHS 上的匹配模式不对应
Type of pattern binder variable on RHS does not correspond to matched pattern on LHS
为什么偏函数
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v.asInstanceOf[Warped[Engineer]]
}
似乎需要 asInstanceOf
在 RHS 上进行转换,而以下则不需要
val engineers: PartialFunction[Crewmember, Engineer] = {
case v@Engineer(name) => v
}
sealed trait Crewmember
case class Engineer(name: String) extends Crewmember
case class Commander(name: String) extends Crewmember
case class Warped[+A <: Crewmember](v: A)
val engineers: PartialFunction[Crewmember, Engineer] = {
case v@Engineer(name) => v
}
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v.asInstanceOf[Warped[Engineer]]
}
val crew: List[Crewmember] =
List(Engineer("Geordi"), Commander("Picard"), Engineer("Scott"), Commander("Kirk"))
val warpedCrew: List[Warped[Crewmember]] =
List(Warped(Engineer("Geordi")), Warped(Commander("Picard")), Warped(Engineer("Scott")), Warped(Commander("Kirk")))
crew collect engineers
// res0: List[Engineer] = List(Engineer(Geordi), Engineer(Scott))
warpedCrew collect warpedEngineers
// res1: List[Warped[Engineer]] = List(Warped(Engineer(Geordi)), Warped(Engineer(Scott)))
可以像这样避免使用 asInstanceOf
进行转换
case Warped(eng: Engineer) => Warped(eng)
但我想知道为什么编译器不插入隐式 asInstanceOf
而是将 v
键入 Warped[Crewmember]
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v
}
Error: type mismatch;
found : Warped[Crewmember]
required: Warped[Engineer]
case v@Warped(Engineer(name: String)) => v
A pattern binder @ consists of a pattern variable and a pattern
. The type of the variable is the static type implied by the
pattern . This pattern matches any value matched by the pattern
, and it binds the variable name to that value.
A pattern implies a type if the pattern matches only values of
the type .
Warped(Engineer(name))
在左边
case v@Warped(Engineer(name: String)) => v
有静态类型 Warped[Crewmember]
因为那是你在类型签名中写的
val warpedEngineers: PartialFunction[Warped[Crewmember], ...
因此,如果您在右侧只写 v
,则类型不匹配。
Warped(Engineer(name))
右边和左边
case Warped(Engineer(name)) => Warped(Engineer(name))
看起来很像,但因为它们有不同的类型而不同。他们实际上是 Warped[Crewmember](Engineer(name))
和 Warped[Engineer](Engineer(name))
。由于协方差 Warped[Engineer]
是 Warped[Crewmember]
但反之则不然。
编译器如何猜测它应该在此处插入 asInstanceOf
而不应在 val x: Int = "a"
中插入?
如果您更改签名
val warpedEngineers: PartialFunction[Warped[Engineer], Warped[Engineer]] = {
case v@Warped(Engineer(name)) => v
}
然后 v
的静态类型将是 Warped[Engineer]
并且代码将编译。
同样,如果您使用类型化模式
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v: Warped[Engineer] => v
}
然后 v
的静态类型将是 Warped[Engineer]
并且代码将编译。
中的规格模式v@Warped(Engineer(name))
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name)) => ...
}
"implies" 输入 Warped[Crewmember]
(因为签名)。
为什么偏函数
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v.asInstanceOf[Warped[Engineer]]
}
似乎需要 asInstanceOf
在 RHS 上进行转换,而以下则不需要
val engineers: PartialFunction[Crewmember, Engineer] = {
case v@Engineer(name) => v
}
sealed trait Crewmember
case class Engineer(name: String) extends Crewmember
case class Commander(name: String) extends Crewmember
case class Warped[+A <: Crewmember](v: A)
val engineers: PartialFunction[Crewmember, Engineer] = {
case v@Engineer(name) => v
}
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v.asInstanceOf[Warped[Engineer]]
}
val crew: List[Crewmember] =
List(Engineer("Geordi"), Commander("Picard"), Engineer("Scott"), Commander("Kirk"))
val warpedCrew: List[Warped[Crewmember]] =
List(Warped(Engineer("Geordi")), Warped(Commander("Picard")), Warped(Engineer("Scott")), Warped(Commander("Kirk")))
crew collect engineers
// res0: List[Engineer] = List(Engineer(Geordi), Engineer(Scott))
warpedCrew collect warpedEngineers
// res1: List[Warped[Engineer]] = List(Warped(Engineer(Geordi)), Warped(Engineer(Scott)))
可以像这样避免使用 asInstanceOf
进行转换
case Warped(eng: Engineer) => Warped(eng)
但我想知道为什么编译器不插入隐式 asInstanceOf
而是将 v
键入 Warped[Crewmember]
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name: String)) => v
}
Error: type mismatch;
found : Warped[Crewmember]
required: Warped[Engineer]
case v@Warped(Engineer(name: String)) => v
A pattern binder @ consists of a pattern variable and a pattern . The type of the variable is the static type implied by the pattern . This pattern matches any value matched by the pattern , and it binds the variable name to that value.
A pattern implies a type if the pattern matches only values of the type .
Warped(Engineer(name))
在左边
case v@Warped(Engineer(name: String)) => v
有静态类型 Warped[Crewmember]
因为那是你在类型签名中写的
val warpedEngineers: PartialFunction[Warped[Crewmember], ...
因此,如果您在右侧只写 v
,则类型不匹配。
Warped(Engineer(name))
右边和左边
case Warped(Engineer(name)) => Warped(Engineer(name))
看起来很像,但因为它们有不同的类型而不同。他们实际上是 Warped[Crewmember](Engineer(name))
和 Warped[Engineer](Engineer(name))
。由于协方差 Warped[Engineer]
是 Warped[Crewmember]
但反之则不然。
编译器如何猜测它应该在此处插入 asInstanceOf
而不应在 val x: Int = "a"
中插入?
如果您更改签名
val warpedEngineers: PartialFunction[Warped[Engineer], Warped[Engineer]] = {
case v@Warped(Engineer(name)) => v
}
然后 v
的静态类型将是 Warped[Engineer]
并且代码将编译。
同样,如果您使用类型化模式
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v: Warped[Engineer] => v
}
然后 v
的静态类型将是 Warped[Engineer]
并且代码将编译。
v@Warped(Engineer(name))
val warpedEngineers: PartialFunction[Warped[Crewmember], Warped[Engineer]] = {
case v@Warped(Engineer(name)) => ...
}
"implies" 输入 Warped[Crewmember]
(因为签名)。