Consider the following example, which should print 8. Why does the A.Value + B.Value thinks that B.Value should be a string? How do I fix it?
object Catano extends App {
val const3 = new Constant(3)
val const5 = new Constant(5)
val block = new Arithmetic(const3.Result, const5.Result)
println(block.Sum.Value)
}
class Block
class Arithmetic[T: Numeric](val A: Connector[T], val B: Connector[T]) extends Block {
def Sum = new Connector({ A.Value + B.Value })
}
class Constant[T](x: T) extends Block {
def Result = new Connector({ x })
}
class Connector[T](f: => T) {
def Value: T = f
}
For type-safety reasons, the following should fail with a Type exception:
val const3 = new Constant("ping")
val const5 = new Constant("pong")
val block = new Arithmetic(const3.Result, const5.Result)
Your problem can be reproduced with just:
What is happening there : in scala as in java, you can do String + anything, and also anything + String. As, unlike in java, pperators are just normal method calls, that seems to imply there is a corresponding + method on each type. Of course, it is not so, as java types have no such method. What we have is
implicit def any2StringAdd(x: Any)inPredef, which makes this+available by implicit conversion. In your code, this is the only + available, which is why it complainsB.Valueis not aString.Now why is the intended
+not available?T:Numericrequires that there is aNumeric[T]value in implicit scope. It says nothing about what type T should be, and what methods are available onT. ThisNumeric[T]instance has adef plus(x: T, y: T): Tmethod. That alone does not make+available on T. You can call plus directly, but this is not covenient. Fortunately, a+delegating topluscan be added by implicit conversion (just like the+(String)was inPredef), provided you put some implicits in scope with :