别名正确的类型作为存在类型(为什么编译?)

时间:2016-09-23 06:56:37

标签: scala

为什么我可以执行以下操作:

class A
type M[_] = A

我希望我只能使用需要一个类型参数的别名,例如List[_],但它也适用于普通类。

如果我创建方法:

def foo(m: M[_]) = m

并使用错误的参数调用它:

scala> foo("a")
<console>:15: error: type mismatch;
 found   : String("a")
 required: M[_]
    (which expands to)  A[]
       foo("a")

我收到这样的错误。 A[]是什么意思?

进一步说明如何解释:

scala> type M[_, _] = A
<console>:12: error: _ is already defined as type _
       type M[_, _] = A

有没有办法确保我在别名右侧的内容是参数化类型?

1 个答案:

答案 0 :(得分:3)

type M[_] = Atype M[X] = A相同:类型的常量函数。 M[X] AXM[Int]AM[String]AM[Any]为{在这种情况下,{1}}等A只是一个标识符(也解释了_的错误)。

当然,在type M[_, _]中,def foo(m: M[_]) = m是一种存在类型:M[_]。我不知道为什么Scala说它在错误消息中扩展为M[T] forSome { type T };这可能是一个错误。您可以通过调用

来检查它与A[]的类型相同
A
  

有没有办法确保我在别名右侧的内容是参数化类型?

您可以使用更高级别的

声明抽象成员类型
scala> implicitly[M[_] =:= A]
res0: =:=[A[],A] = <function1>

并且它只能通过参数化类型实现:

trait Foo { type M[_] }

当然,如第一段所述,class Bar1 extends Foo { type M = Int } // fails class Bar2 extends Foo { type M[X] = List[X] } // works 中的M参数化的,我认为没有办法排除它。< / p>