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
在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 withJava’s generic types
, such asIterator<?> 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