Scala: An extension method was tried, but could not be fully constructed (same extension name on multiple classes)

Viewed 188

In Scala, I'm trying to define an extension method on two different classes. I want the extension method to have the same name, for both classes.

Note that the classes aren't related by inheritance.

As an example, say I have two case classes A and B, each with one String property, and I want to define a lower method on both classes, which will return the lowercase of their property:

import SomeObject.AExt.lower
import SomeObject.BExt.lower

object SomeObject {

  case class A(foo: String)

  case class B(bar: String)

  object AExt {
    extension (x: A) def lower = x.foo.toLowerCase
  }

  object BExt {
    extension (x: B) def lower = x.bar.toLowerCase
  }

  def hello(): Unit = {
    def a = A("foo")

    def b = B("bar")

    println(a.lower)
    println(b.lower)
  }
}

The compilation fails with this error:

An extension method was tried, but could not be fully constructed:

    SomeObject.BExt.lower(a)    failed with

        Found:    SomeObject.A
        Required: SomeObject.B

Looks like the compiler is confused, and is trying to apply the lower extension defined on class B, to my instance of A.

1 Answers

One workaround is to put the extension methods inside the same object:

import SomeObject.ABExt.lower
object SomeObject {

  case class A(foo: String)

  case class B(bar: String)

  object ABExt {
    extension (x: A) def lower = x.foo.toLowerCase
    extension (x: B) def lower = x.bar.toLowerCase
  }

  def hello(): Unit = {
    def a = A("foo")

    def b = B("bar")

    println(a.lower)
    println(b.lower)
  }
}
Related