Sto provando a scrivere codice per rappresentare i polinomi all'interno di Scala. Ho bisogno che questo codice sia di tipo polimorfico, quindi uso impliciti per trattare tipi diversi. Ho:Utilizzo di oggetti impliciti nelle classi
case class Mono[T](degree: Int, coeff: T) {
def Degree: Int = return degree
def Coeff: T = return coeff
}
class Poly[T](private val terms: List[Mono[T]]) {
trait Semiring[T] {
def add(x:T, y:T): T
def mul(x:T, y:T): T
def exponent(x: T, n:Int): T
val unitA: T
}
implicit object IntSemiring extends Semiring[Int] {
def add(x: Int, y: Int): Int = x+y
def mul(x: Int, y: Int): Int = x*y
def exponent(x: Int, n:Int): Int = if(n==0) 1 else x*exponent(x, n-1)
val unitA: Int = 0
}
implicit object SetSemiring extends Semiring[Set[Int]] {
def add(x: Set[Int], y: Set[Int]): Set[Int] = x.union(y)
def mul(x: Set[Int], y: Set[Int]): Set[Int] = x.intersect(y)
def exponent(x: Set[Int], n: Int): Set[Int] = x
val unitA: Set[Int] = Set()
}
def eval(x: T)(implicit r: Semiring[T]): T = {
var termlist = terms
var sum = r.unitA
var expression = terms
while(!termlist.isEmpty) {
val term = expression.head
val power = r.exponent(x, term.Degree)
val termval = r.mul(power, term.Coeff)
sum = r.add(sum, termval)
termlist = termlist.tail
}
return sum
}
def add(that: Poly[T])(implicit r: Semiring[T]): Poly[T] = ...
def mul(that: Poly[T])(implicit r: Semiring[T]): Poly[T] = ...
}
Ho interrotto alcune funzioni per brevità lì. Questo compila benissimo ma quando provo e lo uso io ottenere alcuni strani errori:
scala> val p1 = new Poly(List(Mono(0,1),Mono(1,2),Mono(2,1)))
p1: Poly[Int] = [email protected]
scala> p1 eval 3
<console>:9: error: could not find implicit value for parameter r: p1.Semiring[Int]
p1 eval 3
^
Non sono sicuro di come risolvere il problema. Sto definendo gli oggetti impliciti nel posto sbagliato? Ho provato a spostarli fuori dalla classe, ma poi il compilatore fallisce. C'è qualcos'altro che devo fare per farlo funzionare correttamente?
si potrebbe desiderare di guardare troppo Spire: https://github.com/non/spire: "Spire è una libreria numerico per Scala, che è destinato ad essere generico, veloce e preciso Utilizzando funzioni come specializzazione, macro, classi di tipi e impliciti, Spire lavora sodo per sfidare la saggezza convenzionale intorno alle prestazioni e ai compromessi di precisione. Uno degli obiettivi principali è consentire agli sviluppatori di scrivere codice numerico efficiente senza dover "inserire" particolari rappresentazioni numeriche. Nella maggior parte dei casi, le implementazioni generiche che utilizzano le classi di tipo specializzate di Spire si comportano in modo identico alle corrispondenti implementazioni dirette. " –