James Black
James Black

Reputation: 41858

In Scala 2.10 how to add each element in two generic lists together

I am trying to rewrite some java math classes into Scala, but am having an odd problem.

class Polynomials[@specialized T](val coefficients:List[T]) {
  def +(operand:Polynomials[T]):Polynomials[T] = {
    return new Polynomials[T](coefficients = 
      (operand.coefficients, this.coefficients).zipped.map(_ + _))
  }
}

My problem may be similar to this question: How do I make a class generic for all Numeric Types?, but when I remove the @specialized I get the same error.

type mismatch; found : T required: String

The second underscore in the map function is highlighted for the error, but I don't think that is the problem.

What I want to do is have:

Polynomial(1, 2, 3) + Polynomial(2, 3, 4) return Polynomial(3, 5, 7)

And Polynomial(1, 2, 3, 5) + Polynomial(2, 3, 4) return Polynomial(3, 5, 7, 5)

For the second one I may have to pad the shorter list with zero elements in order to get this to work, but that is my goal on this function.

So, how can I get this function to compile, so I can test it?

Upvotes: 3

Views: 549

Answers (1)

Rex Kerr
Rex Kerr

Reputation: 167891

List is not specialized, so there's not much point making the class specialized. Only Array is specialized.

class Poly[T](val coef: List[T]) {
  def +(op: Poly[T])(implicit adder: (T,T) => T) = 
    new Poly(Poly.combine(coef, op.coef, adder))
}
object Poly {
  def combine[A](a: List[A], b: List[A], f: (A,A) => A, part: List[A] = Nil): List[A] = {
    a match {
      case Nil => if (b.isEmpty) part.reverse else combine(b,a,f,part)
      case x :: xs => b match {
        case Nil => part.reverse ::: a
        case y :: ys => combine(xs, ys, f, f(x,y) :: part)
      }
    }
  }
}

Now we can

implicit val stringAdd = (s: String, t: String) => (s+t)


scala> val p = new Poly(List("red","blue"))
p: Poly[String] = Poly@555214b9

scala>     val q = new Poly(List("fish","cat","dog"))
q: Poly[String] = Poly@20f5498f

scala>     val r = p+q; r.coef
r: Poly[String] = Poly@180f471e
res0: List[String] = List(redfish, bluecat, dog)

You could also ask the class provide the adder rather than the + method, or you could subclass Function2 so that you don't pollute things with implicit addition functions.

Upvotes: 9

Related Questions