在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]
我已经尝试了一段时间,但无法找到正确的方法来成功编译第二个。 所以它只是对方法类型参数的一些限制,或者我在这里遗漏了一些东西。
答案 0 :(得分:5)
令人困惑的是_
中的下划线(foo
)不表示存在类型。
让我们看看以下内容实际意味着什么:
def foo[List[_]](x: List[_]) = x
List
这里是一个更高级的kinded类型参数(顺便说一下,不引用scala的内置List
类型 - aka {{ 1}})。此类型参数本身具有单个类型参数,由下划线(scala.collection.immutable
)表示。
现在很明显_
在这里不是存在主义,因此List[_]
没有业务去那里。
但是,您可以在forSome
类型中使用forSome
。以下内容相当于x
的原始定义:
foo
然后,这可能仍然不是您想要的,因为def foo[List[_]](x: List[T] forSome { type T }) = x
仍然是类型参数而不是 List
。你可能想要的是:
scala.collection.immutable
与:
相同def foo(x: List[T] forSome { type T }) = x
答案 1 :(得分:0)
RégisJean-Gilles暗示“这里的列表是一个更高级的类型参数(顺便说一下,并没有引用Scala的内置List类型 - 又名scala.collection.immutable)”,我有一个检查存在类型的定义,最后在我的案例中找出问题,在这里写下来作为RégisJean-Gilles答案的补充。
存在类型是一种构造类型的方法,其中类型签名的部分是存在的,其中存在意味着虽然
some real type
符合类型签名的那一部分,但我们并不在意关于具体类型。存在类型被引入到Scala中作为与Java’s generic types
进行互操作的方法,例如Iterator<?> or Iterator<? extends Component>
(引自<<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 [_]不是存在类型,因此有些形式不能用于类型参数位置。 以下情况有效。
// 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