2012-02-04 13 views
8

Tengo dificultades para explicar la diferencia de comportamiento entre valores implícitos adicionales buscados por un valor implícito principal o una conversión implícita . En concreto, esto funciona:¿Por qué Scala no puede encontrar un valor implícito secundario en este caso particular?

trait Foo[A] 
implicit def fooString: Foo[String] = null 

implicit def value[A](implicit foo: Foo[A]) = 5 

> implicitly[Int] 
5 

Pero esto no es así:

implicit def conversion[A](x: Int)(implicit foo: Foo[A]) = new { 
    def aMethod = 5 
} 

> 1.aMethod 
could not find implicit value for parameter foo: test.Foo[A] 

Variar:

  • si la búsqueda se inicia por implicitly o una conversión implícita
  • Si lo implícito secundaria valor buscado es polimórfico
  • Si el valor implícito secundario suministrado es polimórfico

consigo los siguientes resultados:

Conversion/value Searching for Supplied | Works? 
---------------- ------------- -------- | ------ 
    conversion  poly   poly | yes 
    conversion  poly   mono | **no** 
    conversion  mono   poly | yes 
    conversion  mono   mono | yes 
    value   poly   poly | yes 
    value   poly   mono | yes 
    value   mono   poly | yes 
    value   mono   mono | yes 

Como se puede ver, el único caso que no funciona es cuando la búsqueda se inicia por una conversión implícita, el valor buscado es polimórfico, sin embargo, el valor suministrado es monomórfico.

¿Hay alguna razón teórica por la cual este debería ser el caso, o es esto un error/limitación de Scala ?

Respuesta

7

Estás siendo mordido por scalac bug SI-3346. Más generalmente vea la descripción de SI-4699, esp. punto (1),

1) Búsqueda búsqueda implícita y conversión implícita tratan a los parámetros de tipo indeterminado diferente

el que se está observando directamente en sus casos están distinguiendo entre los valores implícitos y conversiones implícitas.

He actualizado SI-3346 para incluir esto como un ejemplo adicional.

3

cambiar la firma de la conversión implícita de la siguiente manera:

implicit def conversion[A](a: A)(implicit foo: Foo[A]) = new { 

Entonces llamar aMethod en un valor de tipo para el que se define un valor implícito, es decir, con un cadena:

scala> "foo".aMethod 
res0: Int = 5 
+1

Respuesta correcta, pregunta incorrecta ;-) –

Cuestiones relacionadas