2012-04-01 3 views
1

Je rencontre un problème avec les conversions implicites ne fonctionnant pas dans certaines circonstances (types plus élevés). Avec un système, un type d'expression, et deux sous-types d'expression spécifiques:Conversions implicites ne fonctionnant pas avec les paramètres de type

trait Sys[S <: Sys[S]] 

object Expr { 
    trait Var [S <: Sys[S], A] extends Expr[S, A] 
    trait Const[S <: Sys[S], A] extends Expr[S, A] 
} 
trait Expr[S <: Sys[S], A] 

Et une classe de proxénète pour les opérations d'expression:

class RichDoubleExpr[S <: Sys[S]](ex: Expr[S, Double]) { 
    def gugu(): String = "yes" 
} 

Alors laissez-y les conversions implicites de primitives aux expressions, et de expressions à ops d'expression:

implicit def const[S <: Sys[S]](d: Double): Expr[S, Double] = 
    new Expr.Const[S, Double] {} 

implicit def exprOps[S <: Sys[S], A <% Expr[S, Double]](v: A): RichDoubleExpr[S] = 
    new RichDoubleExpr(v) 

Les ouvrages suivants (donc procédé const implicite):

3.4.gugu() 

Ce qui suit ne le fait pas travail (donc la méthode implicite exprOps):

def test[S <: Sys[S]]: String = { 
    val v = new Expr.Var[S, Double] {} 
    v.gugu() 
} 

avec l'erreur suivante:

error: No implicit view available from java.lang.Object with 
    Expr.Var[S,Double] => Expr[S,Double]. 
      v.gugu() 
     ^

Maintenant, puisque Expr.Var étend Expr et les paramètres de type sont identique, ce message d'erreur n'a clairement aucun sens pour moi. Une idée de comment réparer ça?

Répondre

3

Une solution viable dans mon cas est un peu au paramètre de type 'fix' S:

class ExprImplicits[S <: Sys[S]] { 
    implicit def const(d: Double): Expr[S, Double] = new Expr.Const[S, Double] {} 

    implicit def exprOps[A <% Expr[S, Double]](v: A): RichDoubleExpr[S] = 
    new RichDoubleExpr(v) 
} 

Maintenant, je peux importer les implicits pour un système particulier:

def test[S <: Sys[S]]: String = { 
    val imp = new ExprImplicits[S] 
    import imp._ 

    3.4.gugu() // ok 
    val v = new Expr.Var[S, Double] {} 
    v.gugu() // ok 
} 
Questions connexes