2010-06-23 11 views
3

Je suis en train d'écrire un interpréteur et j'ai essayé d'utiliser la solution de how-to-set-up-implicit-conversion-to-allow-arithmetic-between-numeric-types pour le même problème que je dois être en mesure d'ajouter Booléen + Booléen, Int + Booléen, Booléen + Int, Int + Double, Double + Double etc.comment faire la conversion implicite des types utilisés dans mon interprète

J'utilise des classes WeakConformance et C de cette solution

sealed trait WeakConformance[A <: AnyVal, B <: AnyVal, C] { 
    implicit def aToC(a: A): C 

    implicit def bToC(b: B): C 
} 

object WeakConformance { 
    implicit def SameSame[T <: AnyVal]: WeakConformance[T, T, T] = new WeakConformance[T, T, T] { 
    implicit def aToC(a: T): T = a 

    implicit def bToC(b: T): T = b 
    } 

    implicit def IntDouble: WeakConformance[Int, Double, Double] = new WeakConformance[Int, Double, Double] { 
    implicit def aToC(a: Int) = a 

    implicit def bToC(b: Double) = b 
    } 

    implicit def DoubleInt: WeakConformance[Double, Int, Double] = new WeakConformance[Double, Int, Double] { 
    implicit def aToC(a: Double) = a 

     implicit def bToC(b: Int) = b 
     } 
    } 

    case class C[A <: AnyVal](val value:A) { 
      import WeakConformance.unify 
      def +[B <: AnyVal, WeakLub <: AnyVal](that:C[B])(implicit wc: WeakConformance[A, B, WeakLub], num: Numeric[WeakLub]): C[WeakLub] = { 
     new C[WeakLub](num.plus(wc.aToC(x), wc.bToC(y))) 
     } 
    } 

et est ici une partie de mon interprète

class Interpreter { 

...... 

    def eval(e: Expression): Any = e match { 
    ... 

    case ADD(lhs, rhs) => (eval(lhs), eval(rhs)) match { 

     case (l: C[_], r: C[_]) => l + r // error comes here 

     case _ => error("...") 
    } 
    } 

} 

l'erreur est comme

erreur: valeurs implicites ambiguës: // montre 2 objets derniers déclarés comme implicite dans Numeric trait ici correspondent prévu Type Numeric[WeakLub]

des idées comment le faire fonctionner? Je voulais faire la méthode eval pour revenir C mais depuis C[Int] n'est pas une instance de C[Any] il ne résout pas mon problème

Répondre

1

En raison de l'effacement de type, vous ne pouvez pas récupérer le paramètre de type de C lors de l'exécution. Vous devrez utiliser des manifestes pour stocker ces informations. Voir les questions relatives à l'effacement du manifeste et du type.

+0

Oui, je connais les Manifestes. J'espérais juste que tu suggères un moyen de faire ça. Est-ce que cela signifie que ma méthode eval devrait renvoyer une paire C avec un manifeste au lieu de simplement C? – Tala

+0

Je veux dire que votre _C_ devrait garder un manifeste. Essayez de le déclarer comme ceci: 'classe de cas C [A <: AnyVal] (val valeur: A) (homme implicite: Manifest [A])', et en utilisant ces manifestes pour les lancer dans les types appropriés. –

+0

J'ai changé ma classe C comme vous l'avez conseillé, mais le problème persiste. Pouvez-vous me dire comment je dois modifier le code de l'interpréteur montré ci-dessus? – Tala