Scala &引用;can';参数化类型上的存在抽象…“;

Scala &引用;can';参数化类型上的存在抽象…“;,scala,typeclass,functor,implicits,Scala,Typeclass,Functor,Implicits,为了好玩,我在Scala 2.8上乱搞,试图定义一个函数,它在类型构造函数中添加了一个“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]

为了好玩,我在Scala 2.8上乱搞,试图定义一个函数,它在类型构造函数中添加了一个“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)

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

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

局部定义的类型定义type t=t受存在子句的约束
类型t>:t对我来说,这听起来像是一个简单而不一般的情况:每次创建一个块时,可能会生成一个新的类型变量,捕获一些使用存在类型实例化的类型构造函数,但这会使错误诊断更难理解

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

我习惯于在类似情况下看到错误“结构优化中的参数类型可能不会引用在该优化外部定义的抽象类型”。这种限制与使用反射(IIRC)在JVM上实现结构类型的方式有关。

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

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

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}