Question

I was referring to the generic numeric programming post here. However I am getting compilation error with this code:

object V1 {
  trait Addable[A] {
    self: A =>
    def +(that: A): A
  }

  def add[A <: Addable[A]](x: A, y: A): A = x + y

  implicit class MyInt(x: Int) extends Addable[Int] {
    y: Int =>
    override def +(y: Int): Int = x + y
  }

  def main(args: Array[String]) = {
    add(1, 2)
  }
}

Errors are as shown below:

V1.scala:9: error: `implicit' modifier can be used only for values, variables and methods
  implicit class MyInt(x: Int) extends Addable[Int] {
                 ^
V1.scala:15: error: inferred type arguments [Int] do not conform to method add's type parameter bounds [A <: V1.Addable[A]]
    add(1, 2)
    ^
two errors found

How can I fix the self type?

EDIT: Updated the code and errors.

Essentially, I want to create a generic method that can add two numbers ( Int, Double etc, ).

Was it helpful?

Solution

self: A => means that any class which actually implements this trait has to extend A. The error message class MyInt cannot be instantiated because it does not conform to its self-type V1.MyInt with Int (from comments) basically says that MyInt doesn't extend Int. Since no class can extend Int, Addable[Int] is impossible to implement.

The message inferred type arguments [Int] do not conform to method add's type parameter bounds [A <: V1.Addable[A]] says that Int isn't a subtype of Addable[Int].

How can I fix the self type?

This approach simply won't work with Int. The standard approach uses the type class pattern. In particular for

Essentially, I want to create a generic method that can add two numbers ( Int, Double etc, ).

there is already a type class Numeric[T] in the standard library:

def add[A](x: A, y: A)(implicit n: Numeric[A]) = n.plus(x, y) // or simply x + y
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top