2012-11-01 12 views
6

I wydaje się, że połączenie niejawne konwersje z ogólnych parametrów ukrytych nie działa, tak jak w przykładzie 2b poniżej:niejawna konwersja z rodzajowego parametr niejawny

object Test { 

    case class Foo(i: Int) 
    case class Bar(i: Int) 
    case class Zip(i: Int) 

    object Foo { 
    // 1) 
    implicit def toBar(foo: Foo)(implicit g: Int => Bar): Bar = g(foo.i) 
    // 2) 
    implicit def toT[T](foo: Foo)(implicit g: Int => T): T = g(foo.i) 
    } 

    // 1) 
    implicit val b = (i: Int) => Bar(i) 
    val bar: Bar = Foo(3)  

    // 2a) 
    implicit val z = (i: Int) => Zip(i) 
    val zip: Zip = Foo.toT(Foo(3)) 

    // 2b) 
    val zip2: Zip = Foo(3) // <- compiler error, implicit conversion not applied 

} 

Czy istnieje teoretyczna powód ten nie działa, lub jest to ograniczenie wdrożenia?

Odpowiedz

2

Na co warto, jeśli uruchomić następujące zmniejszoną wersję kodu

case class Foo(i: Int) 
case class Zip(i: Int) 

implicit def toT[T](foo: Foo)(implicit g: Int => T): T = g(foo.i) 

implicit val z = (i: Int) => Zip(i) 

val zip2: Zip = Foo(3) // <- compiler error, implicit conversion not applied 

z -Yinfer-debug, dostaniesz lots of debug information (Scala 2.9.2) o tym, co dzieje się za kulisami. Nie jestem zaznajomiony z wewnętrznymi kompilatorami Scala, ale następujące dwa fragmenty wyjściowe mogą wskazywać na problem. Pierwszym z nich jest (linia 51ff z GIST)

[inferImplicit view] pt = this.Foo => this.Zip 
Implicit search in Context([email protected] scope=1100551785) { 
    search this.Foo => this.Zip 
    target $anon.this.Foo.apply(3) 
    isView true 
    eligible toT: [T](foo: this.Foo)(implicit g: Int => T)T 
} 

i interpretować je jako „szukamy niejawny this.Foo => this.Zip i kandydata warto spojrzeć na to toT: [T](foo: this.Foo)(implicit g: Int => T)T. Ten fragment jest po wyjściu, co sugeruje, że Scala następnie próbuje instancję T, ale linia 81 w końcu mówi

inferMethodInstance, still undetermined: List(type T) 

Moja interpretacja jest taka, że ​​Scala jakoś nie trafia do wystąpienia T z Zip, dlatego kandydat zostaje ostatecznie odrzucony.


To powiedziawszy, nie widzę teoretycznego problemu z kodem i zakładam, że jest to tylko wada kompilatora.