简体   繁体   English

Scala:F-有界多态性困境

[英]Scala: F-Bounded Polymorphism Woes

Assume the existence of the following types and method: 假设存在以下类型和方法:

trait X[A <: X[A]]

case class C extends X[C]

def m(x: PartialFunction[X[_], Boolean])

I want to be able to create a PartialFunction to be passed into m . 我希望能够创建一个要传递给m的PartialFunction。

A first attempt would be to write 第一次尝试就是写作

val f: PartialFunction[X[_], Boolean] = { 
  case c: C => true
}

m(f)

This fails with type arguments [_$1] do not conform to trait X's type parameter bounds [A <: X[A]] . 这种type arguments [_$1] do not conform to trait X's type parameter bounds [A <: X[A]]失败type arguments [_$1] do not conform to trait X's type parameter bounds [A <: X[A]] So, it seems we have to constraint X 's type parameters. 所以,似乎我们必须约束X的类型参数。

A second attempt: 第二次尝试:

val f: PartialFunction[{type A <: X[A]}, Boolean] = { 
  case c: C => true
}

m(f)

This fails on the application of m because PartialFunction[AnyRef{type A <: X[this.A]},Boolean] <: PartialFunction[X[_],Boolean] is false. 由于PartialFunction[AnyRef{type A <: X[this.A]},Boolean] <: PartialFunction[X[_],Boolean]为false PartialFunction[AnyRef{type A <: X[this.A]},Boolean] <: PartialFunction[X[_],Boolean]因此无法应用m

Is there any way not involving casting that actually satisfies the compiler both on the definition of the partial function and on the application of m ? 有没有任何方法不涉及在部分函数的定义和m的应用上实际满足编译器的转换?

Not sure if that's what you wanted to achieve, but this is the working sequence: 不确定这是否是你想要实现的,但这是工作顺序:

trait X[A <: X[A]]
case class C extends X[C]
def m[T<:X[T]](x: PartialFunction[X[T], Boolean]) = print("yahoo!")

scala> def f[T<:X[T]]:PartialFunction[X[T], Boolean] = {
     | case c: C => true
     | }
f: [T <: X[T]]=> PartialFunction[X[T],Boolean]

scala> m(f)
yahoo!

I'm not sure what exactly you want, but since you are using an existential type (in disguise of the _ syntax), this is how you can make that work: 我不确定你究竟想要什么,但由于你使用的是存在类型(以伪装的_语法),这就是你如何做到这一点:

val f: PartialFunction[X[A] forSome {type A <: X[A]}, Boolean] = {
  case c : C => true
}

The _ syntax isn't good enough here, since you need to give the existential type the right upper bound. 这里的_语法不够好,因为你需要给存在类型赋予正确的上限。 That is only possible with the more explicit forSome syntax. 只有使用更明确的forSome语法才能实现这一点。

What I find surprising, though, is that Scala accepts the declaration 但令我惊讶的是,Scala接受了声明

def m(x: PartialFunction[X[_], Boolean])

in the first place. 首先。 It seems weird that it even considers X[_] a well-formed type. 它甚至认为X[_]是一个结构良好的类型似乎很奇怪。 This is short for X[A] forSome {type A <: Any} , which should not be a valid application of X , because it does not conform to the parameter bounds. 这是X[A] forSome {type A <: Any} ,它不应该是X的有效应用程序,因为它不符合参数边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM