【问题标题】:Scala: F-Bounded Polymorphism WoesScala:F-Bounded Polymorphism Woes
【发布时间】:2013-11-21 17:58:41
【问题描述】:

假设存在以下类型和方法:

trait X[A <: X[A]]

case class C extends X[C]

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

我希望能够创建一个 PartialFunction 以传递给m

第一次尝试是写

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

m(f)

type arguments [_$1] do not conform to trait X's type parameter bounds [A &lt;: X[A]] 失败。所以,看来我们必须约束X 的类型参数。

第二次尝试:

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

m(f)

m 申请失败,因为PartialFunction[AnyRef{type A &lt;: X[this.A]},Boolean] &lt;: PartialFunction[X[_],Boolean] 为假。

在偏函数的定义和m的应用上,有什么方法不涉及实际满足编译器的强制转换?

【问题讨论】:

    标签: scala generics types compilation structural-typing


    【解决方案1】:

    我不确定您到底想要什么,但由于您使用的是存在类型(伪装成 _ 语法),因此您可以这样工作:

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

    _ 语法在这里不够好,因为您需要为存在类型提供右上界。这只有通过更明确的forSome 语法才能实现。

    但令我惊讶的是,Scala 接受了声明

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

    首先。它甚至认为X[_] 是一种格式良好的类型,这似乎很奇怪。这是X[A] forSome {type A &lt;: Any}的缩写,它不应该是X的有效应用,因为它不符合参数边界。

    【讨论】:

      【解决方案2】:

      不确定这是否是您想要实现的目标,但这是工作顺序:

      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!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-27
        • 2012-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-08
        • 2015-05-13
        相关资源
        最近更新 更多