代码之家  ›  专栏  ›  技术社区  ›  Landei

高级类型的隐式参数解析

  •  9
  • Landei  · 技术社区  · 14 年前

    请考虑以下代码:

    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])  //???
        }
    }
    

    这是可行的,但我需要键入一些(42)作为选项[int],否则将无法解析隐式对象选项栏(因为需要一个条[some])。有没有一种方法可以避免显式键入,以便在测试中获得隐式OptionBar对象,即使我用一些或没有的方法来提供测试?

    [澄清]

    • 我在这里使用了选项作为例子,如果我有一个 Bar 抽象类等。
    • 当其他不相关的条在范围内时,解决方案也应该有效,比如 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))
      }
    }
    

    当然,这是酒吧的一个严重限制,所以我仍然希望有更好的答案。

    2 回复  |  直到 13 年前
        1
  •  7
  •   Community CDub    8 年前

    它不会在所有情况下都起作用,但如前所述,您可以尝试以下方法:

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

    有趣的是,虽然它表达了同样的东西,但这并不能推断出:

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

    了解更多信息 <:< 见:

        2
  •  5
  •   Daniel C. Sobral    14 年前

    那是因为 Some(42) 是比 Option[Int] . 这是一个 Some[Int] . 参见下面的备选编码:

    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(Option(42))
        }
    }
    
    推荐文章
    alphacentauri  ·  HOMap实现示例
    11 年前