2011-03-11 3 views
4

Existe-t-il un moyen de faire en sorte que cela fonctionne? (Scala 2.8.1)Conversion implicite d'un conteneur générique pour un paramètre implicite dans Scala

class A 
def f(implicit a: A) = 0 

class Vendor[T](val v: T) 
implicit val vendor = new Vendor(new A) 
implicit def vendorToVal[T](implicit v: Vendor[T]) = v.v 
f 

L'erreur est: 'divergente extension implicite de type A à partir de la méthode vendorToVal'

Ceci est lié à lever 2,2 injection de dépendance, le code réel ressemble à ceci:

class UserStore(implicit db: DbAccess) 
object DependencyFactory extends Factory { 
    implicit val db = new FactoryMaker[DbAccess](Model) {} 
    import db._ // implicit conversion would allow to remove this import 

    implicit val userStore = new FactoryMaker[UserStore](new UserStore) {} 
} 

cette question est liée à: Is there a way to implicitly convert an implicit parameter in Scala?

+0

Ma solution finale au problème Lift DI est d'utiliser les importations au lieu des arguments implicites des dépendances. Détails: http://scala-notes.blogspot.com/2011/03/dependency-injection-with-lift.html –

Répondre

3

Le problème est dû à la méthode vendorToVal - J'ai observé le même comportement plusieurs fois, lorsque j'utilisais des paramètres implicites dans des méthodes implicites paramétrées par type. Malheureusement, je n'ai trouvé aucune colle simple et élégante dans 2.8._.

Quelques discussions intéressantes, liées au thème:

  1. http://scala-programming-language.1934581.n4.nabble.com/scala-Why-is-this-a-diverging-implicit-td1998156.html
  2. http://www.scala-lang.org/node/6847
1

Scala 2.9 tronc, vous pouvez le faire:

scala> class A 
defined class A 

scala> def f(implicit a: A) = 0 
f: (implicit a: A)Int 

scala> 

scala> class Vendor[T](val v: T) 
defined class Vendor 

scala> implicit def value[T: Vendor] = implicitly[Vendor[T]].v 
value: [T](implicit evidence$1: Vendor[T])T 

scala> implicit val vendor = new Vendor(new A) 
vendor: Vendor[A] = [email protected] 

scala> f 
res0: Int = 0 

Appel f recherchera une valeur de type A, et trouver le value[A] implicite, ce qui nécessite un paramètre de preuve de type Vendor[A]. Il résout ce paramètre de preuve à vendor.

Je ne pense pas que les implicits étaient si puissants dans 2.8.1.

+2

Dans ma version de 2.9.0 il casse, quand j'ajoute un 'Vendeur' implicite pour une autre classe à le même contexte: 'classe B; implicit val vendor_b = nouveau fournisseur (nouveau B) ' –

+1

True. Dans ce cas, je suppose qu'on pourrait encore écrire 'f (value [A])', mais cela bat le sens .. – axel22