Scala 方法类型参数不能接受 forSome 形式的存在类型

Scala method type parameter can not accept existential type in forSome form

在Scala中,存在类型有以下两种形式:

 // placeholder syntax
 List[_]
 // forSome
 List[T forSome {type T}]

但是,第二种形式似乎不能出现在方法类型参数位置(至少在我下面写的方式中)。

  // placeholder syntax is Okay
  scala> def foo[List[_]](x: List[_]) = x
  foo: [List[_]](x: List[_])List[_]

  scala> def foo[List[t forSome {type t}]](x: List[_]) = x
  <console>:1: error: ']' expected but 'forSome' found.
  def foo[List[T forSome {type T}]](x: List[_]) = x
                  ^

  // being as upper bound is also Okay
  scala> def foo[A <: List[T forSome { type T }]](x: A) = x
  foo: [A <: List[T forSome { type T }]](x: A)A

  // type alias is a possible way but that is not what I want
  scala> type BB = List[T forSome {type T}]
  defined type alias BB

  scala> def foo[BB](x: List[_]) = x
  foo: [BB](x: List[_])List[Any]

我已经尝试了一段时间,但一直找不到正确的方法来使第二个编译成功。 那么它只是对方法类型参数的一些限制,还是我在这里遗漏了什么。

令人困惑的是 foo 中的下划线 (_) 表示存在类型。

让我们看看以下内容的实际含义:

def foo[List[_]](x: List[_]) = x

List 这是一个更高种类的类型参数(顺便说一下,not 指的是 scala 的内置 List 类型——又名 scala.collection.immutable).此类型参数本身有一个类型参数,由下划线 (_).

表示

现在很明显 List[_] 在这里不存在,因此 forSome 没有业务去那里。

但是,你可以在x的类型中使用forSome。以下等同于您对 foo 的原始定义:

def foo[List[_]](x: List[T] forSome { type T }) = x

话又说回来,这可能仍然不是您想要的,因为 List 仍然是一个类型参数,而 不是 scala.collection.immutable。您可能想要的是:

def foo(x: List[T] forSome { type T }) = x

等同于:

def foo(x: List[_]) = x

受到 Régis Jean-Gilles 的提示 "List here is a higher-kinded type parameter (and by the way does not refer to Scala's built-in List type -- aka scala.collection.immutable)",我重新检查了存在类型的定义,终于弄清楚了我的问题,就把它写在这里作为对 Régis Jean-Gilles 的补充回答。

Existential types are a means of constructing types where portions of the type signature are existential, where existential means that although some real type meets that portion of a type signature, we don’t care about the specific type. Existential types were introduced into Scala as a means to interoperate with Java’s generic types, such as Iterator<?> or Iterator<? extends Component>(Quote from <<Scala In Depth>>).

实际类型可以是库中的类型(如 scala.collection.immutable.List),也可以是自定义类型,如我的类型别名 BB。无论如何,Scala 编译器必须保证 存在类型的一部分也是已知的

我的问题是

 // List is type parameter which accepts another type as parameter
 def foo[List[_]](x: List[_]) = x
 // List may be misleading here, just change it to another name
 def foo[TT[_]](x: TT[_]) = x

Scala 编译器只知道 TT 是更高种类的类型参数,显然这里不存在真正的类型。所以在这种情况下,TT[_] 不是存在类型因此 forSome 形式不能用于类型参数位置。 以下情况有效。

// we define a higher-kined type HKT, so HKT is a real type 
// when Scala compiler checks the method parameter part
// HKT can be defined as existential type
def foo[HKT[_]](x: HKT[T forSome { type T }]) = x
def foo[HKT[_]](x: HKT[T] forSome { type T }) = x