9

次のコードを検討してください。

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 オブジェクトを取得できますか?

【説明】

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

しかしもちろん、これは Bar の可能性の深刻な制限であるため、私はまだより良い答えを望んでいます.

4

2 に答える 2

7

すべての場合にうまくいくわけではありませんが、前述のように、これを試すことができます。

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]) = ()

の詳細について<:<は、次を参照してください。

于 2010-09-28T20:06:19.543 に答える
5

これ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))
    }
}
于 2010-09-28T20:18:25.407 に答える