All*_*hou 2 types scala existential-type
在Scala中,存在类型有以下两种形式:
// placeholder syntax
List[_]
// forSome
List[T forSome {type T}]
Run Code Online (Sandbox Code Playgroud)
但是,似乎第二种形式不能出现在方法类型参数位置(至少在我写下面的方式).
// 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]
Run Code Online (Sandbox Code Playgroud)
我已经尝试了一段时间但无法找到正确的方法来成功编译第二个.所以它只是对方法类型参数的一些限制,或者我在这里遗漏了一些东西.
这种混淆是下划线(_)中foo不不表示一种存在类型.
让我们看看以下内容实际意味着什么:
def foo[List[_]](x: List[_]) = x
Run Code Online (Sandbox Code Playgroud)
List这是一个更高的kinded类型参数(并且顺便说一下,并不是指scala的内置List类型 - 又名scala.collection.immutable).此类型参数本身具有单个类型参数,由下划线(_)表示.
现在很明显,List[_]这里并不是一个存在主义,因此forSome没有业务去那里.
但是,您可以使用forSome的类型x.以下内容相当于您原来的定义foo:
def foo[List[_]](x: List[T] forSome { type T }) = x
Run Code Online (Sandbox Code Playgroud)
然后,这可能仍然不是你想要的,因为List它仍然是一个类型参数而不是 scala.collection.immutable.你可能想要的是:
def foo(x: List[T] forSome { type T }) = x
Run Code Online (Sandbox Code Playgroud)
这与:
def foo(x: List[_]) = x
Run Code Online (Sandbox Code Playgroud)