scala - "can' t 存在性抽象参数化类型..."

标签 scala typeclass functor implicits

为了好玩,我在 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以及附加类(class) 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 中的以下语句块:

A locally defined type definition type t = T is bound by the existential clause type t >: T <: T . It is an error if t carries type parameters.



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

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

是一个简写

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

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

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}

关于scala - "can' t 存在性抽象参数化类型...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3122398/

相关文章:

scala - 如何为 IntelliJ 安装 Scala 插件

scala - 与 '' this'' 没有类型/差异的显式自引用

scala - 在函数式 Scala 中,将一种参数化类型转换为另一种参数化类型的好方法是什么?

python - 平凡仿函数

scala - 将 Yarn 集群配置添加到 Spark 应用程序

scala - 如何向上转换 monad 变压器类型?

haskell - 类型类约束的存在量化

haskell - 为什么 ghci 输出 (Num a) => a for :t 4 and not (Ord a) => a?

用于执行控制的 c++ 函数代理

C++ 将函数传递给仿函数