【问题标题】:"can't existentially abstract over parameterized type..."“不能对参数化类型进行存在抽象......”
【发布时间】:2011-03-08 12:50:38
【问题描述】:

我为了好玩而玩弄 Scala 2.8 并试图定义一个 pimp,它为类型构造函数添加了一个“as”方法,允许从一个函子转换为另一个函子(请忽略我不一定在这里处理函子)。例如,您可以像这样使用它:

val array:Array[T]
val list:List[T] = array.as[List]

这就是我尝试做的事情:

object Test {
    abstract class NatTrans[F[_], G[_]] {
        def convert[T](f:F[T]):G[T]
    }

    implicit def array2List:NatTrans[Array, List] = new NatTrans[Array, List] { 
        def convert[T](a:Array[T]) = a.toList
    }

    // this next part gets flagged with an error
    implicit def naturalTransformations[T, F[_]](f:F[T]) = new {
        def as[G[_]](implicit n:NatTrans[F, G]) = n convert f
    }
}

但是naturalTransformations 的定义被标记为错误“不能在参数化类型 G[T] 上存在抽象”。为了解决这个问题,我可以重写naturalTransformations 以及一个额外的类Transformable,如下所示:

class Transformable[T, F[_]](f:F[T]) {
    def as[G[_]](implicit n:NatTrans[F, G]) = n convert f
}

implicit def naturalTransformations[T, F[_]](f:F[T]) = new Transformable[T, F](f)

它似乎工作。但似乎我的第一次尝试应该是等效的,所以我很好奇它为什么失败以及错误消息的含义。

【问题讨论】:

  • 我习惯于在类似情况下看到错误“结构细化中的参数类型可能未引用该细化之外定义的抽象类型”。该限制与在 JVM 上通过反射 IIRC 实现结构类型的方式有关。 stackoverflow.com/questions/2685804/…

标签: scala typeclass functor implicits


【解决方案1】:

我的直觉是,这是因为规范中的以下语句,第 6.11 节,块:

本地定义的类型定义类型 t = T 受存在子句的约束 键入 t >: T <: t>

并且结构实例创建表达式被评估为一个块,所以


new {def greet{println("hello")}}

的简写

{ class anon$X extends AnyRef{ def greet = println("hello") }; new anon$X }

因此它计算为一个块表达式(根据规范的第 6.10 节),具有上述限制。但是,我不知道为什么会有这种限制。可以在 this location 的 Typers 类中找到引发的错误,这似乎证实了此限制是您看到的错误的原因。 正如您所提到的,在类中对函数进行编码消除了块表达式的限制:


scala> class N[M[_]]
defined class N

scala> class Q { def as[M[_]](n:N[M]) = null}
defined class Q

scala> new { def as[M[_]](n:N[M]) = null}       
:7: error: can't existentially abstract over parameterized type M
       new { def as[M[_]](n:N[M]) = null}

【讨论】:

    【解决方案2】:

    对我来说,这听起来像是一个针对一般性的简单案例:每次创建一个块时都会生成一个新的类型变量,以捕获一些以存在类型实例化的类型构造函数,但这会使错误诊断更加难以理解。

    另请注意,拥有一个类会将调用转换为快速 INVOKEVIRTUAL,而不是通过反射调用 as() 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 2017-05-19
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      相关资源
      最近更新 更多