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
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
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. –
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