具有更高种类类型的上下文边界快捷方式
是否可以将上下文边界语法快捷方式与更高种类的类型一起使用?
trait One { def test[W : ClassManifest]: Unit } // first-order ok
trait Two { def test[W[_]: ClassManifest]: Unit } // not possible??
trait Six { def test[W[_]](implicit m: ClassManifest[W[_]]): Unit } // hmm...
Is it possible to use the context bounds syntax shortcut with higher kinded-types?
trait One { def test[W : ClassManifest]: Unit } // first-order ok
trait Two { def test[W[_]: ClassManifest]: Unit } // not possible??
trait Six { def test[W[_]](implicit m: ClassManifest[W[_]]): Unit } // hmm...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,确实如此,但是您的上下文绑定类型必须具有更高种类的类型参数(ClassManifest 没有)。
更新
可以使用类型别名来允许更高种类的类型参数受一阶上下文绑定类型的限制。我们使用类型别名作为类型级函数,从一阶类型中生成更高类型的类型。对于 ClassManifest 可以这样,
请注意,类型别名 CC[_] 的右侧是一阶类型...这里的下划线是通配符。因此它可以用作 ClassManifest 的类型参数。
更新
为了完整起见,我应该注意类型别名可以使用类型 lambda 内联,
Yes, it is, but your context bound type must have a higher kinded type parameter (which ClassManifest doesn't).
Update
It's possible to use a type alias to allow a higher-kinded type parameter to be bounded by a first-order context bound type. We use the type alias as a type-level function to make a higher-kinded type out of the first-order type. For ClassManifest it could go like this,
Note that on the right hand side of the type alias CC[_] is a first-order type ... the underscore here is the wildcard. Consequently it can be used as the type argument for ClassManifest.
Update
For completeness I should note that the type alias can be inlined using a type lambda,
请注意,
implicitly[ClassManifest[List[_]]]
是implicitly[ClassManifest[List[T] forSome {type T}]]
的缩写。这就是它工作的原因:
ClassManifest
需要一个正确的类型参数,而List[T] forSome {type T}
是一个正确的类型,但是List
是一个类型构造函数。 (请参阅 Scala 中更高种类的类型是什么? 来定义“正确”等。)为了使
ClassManifest[List[String]]
和ClassManifest[List]
都能工作,我们需要以某种方式重载ClassManifest
,其版本采用不同类型的类型参数,例如:(在学术笔记中,“正确”的方法是允许对类型进行抽象
:)
Note that
implicitly[ClassManifest[List[_]]]
is short forimplicitly[ClassManifest[List[T] forSome {type T}]]
.That's why it works:
ClassManifest
expects a proper type argument, andList[T] forSome {type T}
is a proper type, butList
is a type constructor. (Please see What is a higher kinded type in Scala? for a definition of "proper" etc.)To make both
ClassManifest[List[String]]
andClassManifest[List]
work, we'd need to overloadClassManifest
somehow with versions that take type parameters of varying kinds, something like:(On an academic note, the "proper" way to do this, would be to allow abstracting over kinds:
)