更高种类的隐式参数解析 [英] Implicit parameter resolution for higher kinded types

查看:91
本文介绍了更高种类的隐式参数解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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]).有没有一种方法可以避免进行显式输入,以便即使我使用某些"或无"输入测试,也可以在测试中获得隐式的OptionBar对象?

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?

[澄清]

  • 我在这里以Option为例,如果我为抽象类等使用Bar,它也应该工作.
  • 当其他不相关的条形图在范围内(例如,implicit object listBar extends Bar[list]
  • )时,该解决方案也应该起作用
  • 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]

[更新]

似乎使Bar的参数成为协变量可以达到目的:

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))
  }
}

但是,这当然是对Bar可能性的严重限制,因此我仍然希望有一个更好的答案.

But of course this is a severe limitation of the possibilities in Bar, so I still hope for a better answer.

推荐答案

它并非在所有情况下都有效,但是如上所述,您可以尝试以下方法:

It's not going to work in all cases, but as stated, you can try this:

object foo {
  trait Bar[Q[_]]

  implicit object OptionBar extends Bar[Option]

  def test[T, C[_], D](c: D)(implicit bar: Bar[C], ev: D <:< C[T]) = ()

  def main(args: Array[String]) {
    test(Some(42)) //???
  }
}

有趣的是,尽管它表达了相同的内容,但这并不能推断:

Interestingly, this doesn't infer, although it expresses the same thing:

def test[T, C[_], D <: C[T]](c: D)(implicit bar: Bar[C]) = ()

要了解有关<:<的更多信息,请参见:

To learn more about <:<, see:

  • What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?
  • <:< operator in scala

这篇关于更高种类的隐式参数解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆