“不能在参数化类型上本质上抽象..." [英] "can't existentially abstract over parameterized type..."

查看:84
本文介绍了“不能在参数化类型上本质上抽象..."的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩弄Scala 2.8,试图定义 pimp 会在类型构造函数中添加一个"as"方法,允许从一个函子转换为另一个函子(请忽略这一事实,在此我不一定要处理函子).因此,例如,您可以像这样使用它:

I was messing around with Scala 2.8 for fun and trying to define a pimp which adds an "as" method to type constructors, allowing to convert from one functor to another (please overlook the fact that I'm not necessarily dealing with functors here). So for instance, you could use it like this:

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

这就是我尝试做的事情:

So here's what I tried to do:

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:

however the definition of naturalTransformations is flagged with the error "can't existentially abstract over parameterized type G[T]". To fix this, I can rewrite naturalTransformations along with an additional class Transformable like so:

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)

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

and it appears to work. But it seems like my first attempt should've been equivalent, so I'm curious why it failed and what the error message means.

推荐答案

我的直觉是,这是由于规范中的以下语句§造成的. 6.11,块:

My hunch would be that this is because due to the following statements in the spec, § 6.11 , blocks:

本地定义的类型定义类型t = T受存在子句约束 类型t>:T< ;: T.如果t携带类型参数,这是一个错误.

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.

结构实例创建表达式被求值为一个块,所以

And a structural instance creation expression is evaluated to a block, so


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


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

因此,在有上述限制的情况下,它求值为块表达式(根据本规范的6.10节).我不知道为什么会有这个限制.可以在

so it evaluates to a block expression (according to § 6.10 of the spec), with the aforementioned restriction. Why this restriction is there I do not know, however. The error that is thrown can be found in the Typers class at this location, which seems to confirm that this restriction is the cause of the error that you see. As you mentioned, encoding the function in a class removes the block expression restriction:


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}

这篇关于“不能在参数化类型上本质上抽象..."的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆