更高种类类型的隐式参数解析
考虑以下代码:
object foo {
trait Bar[Q[_]]
implicit object OptionBar extends Bar[Option]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) = ()
def main(args: Array[String]) {
test(Some(42): Option[Int]) //???
}
}
这可行,但我需要将 Some(42) 输入为 Option[Int],否则隐式对象 OptionBar 将无法解析(因为需要 Bar[Some])。有没有办法避免显式键入,以便即使我使用 Some 或 None 提供测试,我也会在测试中获得隐式 OptionBar 对象?
[澄清]
- 我在这里使用 Option 只是作为示例,如果我有一个用于抽象类等的
Bar
,它也应该起作用。 - 当其他不相关的 Bars 在范围内时,该解决方案也应该起作用,比如
implicit object listBar extends Bar[list]
[更新]
似乎使 Bar 的参数逆变可以解决问题:
object foo {
trait Bar[-Q[_]] //<---------------
implicit object OptionBar extends Bar[Option]
implicit object ListBar extends Bar[List]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) = ()
def main(args:Array[String]) {
test(Some(42))
}
}
但当然这是对 Bar 中可能性的严重限制,所以我仍然希望有一个更好的答案。
Consider the following code:
object foo {
trait Bar[Q[_]]
implicit object OptionBar extends Bar[Option]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) = ()
def main(args: Array[String]) {
test(Some(42): Option[Int]) //???
}
}
This works, but I need to type the Some(42) as Option[Int], else the implicit object OptionBar won't be resolved (because a Bar[Some] is expected instead). Is there a way to avoid the explicit typing, so that I get the implicit OptionBar object in test even if I feed test with a Some or None?
[Clarification]
- I used Option here just as example, it should also work if I have a
Bar
for an abstract class etc. - The solution should also work when other, unrelated Bars are in scope, say
implicit object listBar extends Bar[list]
[Update]
It seems that making Bar's parameter contravariant does the trick:
object foo {
trait Bar[-Q[_]] //<---------------
implicit object OptionBar extends Bar[Option]
implicit object ListBar extends Bar[List]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) = ()
def main(args:Array[String]) {
test(Some(42))
}
}
But of course this is a severe limitation of the possibilities in Bar, so I still hope for a better answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它不会在所有情况下都有效,但如上所述,您可以尝试以下操作:
有趣的是,这并不能推断,尽管它表达了相同的内容:
要了解有关
<:<
的更多信息,请参阅:It's not going to work in all cases, but as stated, you can try this:
Interestingly, this doesn't infer, although it expresses the same thing:
To learn more about
<:<
, see:这是因为
Some(42)
是比Option[Int]
更具体的类型。它是一个Some[Int]
。请参阅下面的替代编码:That's because
Some(42)
is a more specific type thanOption[Int]
. It is aSome[Int]
. See alternative coding below: