Search code examples
scalascala-3

Scala 3 fails to match a method to an equivalent function signature?


I'm on Scala 3.2.1, and the code below fails to compile.

class Test[F[_]] {
  def error(message: => String): F[Unit] = {??? }
  def error(t: Throwable)(message: => String): F[Unit] = {??? }

  def test1(f: String => F[Unit]): Unit = {}
  def test2(f: Throwable => String => F[Unit]): Unit = {}

  test1(error)
  test2(error)
}

test1 line compiles fine, but test2 breaks with

None of the overloaded alternatives of method error in class Test with types
 (t: Throwable)(message: => String): F[Unit]
 (message: => String): F[Unit]
match expected type Throwable => String => F[Unit]
  test2(error)

Substituting F[Unit] for just Unit works, so I'm suspecting some kind of type erasure issue...? Do I need to put a ClassTag somewhere...?


Solution

  • Your second overloaded error

    def error(t: Throwable)(message: => String): F[Unit] = {??? }
    

    has => String as the type of the second parameter, not String. These two types are not the same: first is a potentially side-effecty function that can be re-run multiple times (or not at all), whereas the second is just a pure string.

    If you adjust the signature of the second test accordingly to

    def test2(f: Throwable => (=> String) => F[Unit]): Unit = {}
    

    it compiles at least with 3.2.0, I don't expect 3.2.1 to be much different here.