question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Operator overloading rules changes on 3.0.0

See original GitHub issue

Porting spire shows a change (Couldn’t find any mention to this in the docs) from Scala 2.13 and 3.0 on operator overloading. This is repeated across the codebase which contains overloads to common operators like + and -. The code below is a minimization that compiles in 2.13 but fails in 3.0

A repo with the issue can be found at

https://github.com/cquiroz/implicit-operator

Compiler version

Scala 2.13 and 3.0.0.

Minimized code


import algebra.ring.AdditiveSemigroup
import algebra.ring.CommutativeSemiring
import algebra.Semigroup
import algebra.Monoid

final class AdditiveSemigroupOps[A](lhs: A)(implicit as: AdditiveSemigroup[A]) {
  def +(rhs: A): A = as.plus(rhs, lhs)
  def ^(rhs: A): A = as.plus(rhs, lhs)
}

trait AdditiveSemigroupSyntax {
  implicit def additiveSemigroupOps[A: AdditiveSemigroup](
      a: A
  ): AdditiveSemigroupOps[A] = new AdditiveSemigroupOps(a)
}

object syntax {
  object additiveSemigroup extends AdditiveSemigroupSyntax
}

object App {
  def main(args: Array[String]): Unit = {
    import syntax.additiveSemigroup._
    implicit def IntAlgebra[A]: AdditiveSemigroup[Map[Int, A]] = ???

    def res[A]: Map[Int, A] = {
      val a: Map[Int, A] = Map.empty
      val b: Map[Int, A] = Map.empty
      // Calls the operator on AdditiveSemigroupOps
      a ^ b
      // Calls the operator + on AdditiveSemigroupOps only in Scala 2
      // In Scala 3 tries to call `+` on Map
      a + b
    }
  }

}

Output

// Only in Scala 3.0
[error] -- [E007] Type Mismatch Error: /Users/cquiroz/Projects/implicit-operator/src/main/scala/Main.scala:33:10
[error] 33 |      a + b
[error]    |          ^
[error]    |          Found:    (b : Map[Int, A])
[error]    |          Required: (Int, A)

Expectation

To cross compile or have some way to override de + operator like with the ^ operator.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
bishaboshacommented, Jun 4, 2021

version without spire dependency:

import language.implicitConversions

trait AdditiveSemigroup[A]

final class AdditiveSemigroupOps[A](lhs: A)(implicit as: AdditiveSemigroup[A]) {
  def +(rhs: A): A = ???
  def ^(rhs: A): A = ???
}

trait AdditiveSemigroupSyntax {
  implicit def additiveSemigroupOps[A: AdditiveSemigroup](a: A): AdditiveSemigroupOps[A] =
     new AdditiveSemigroupOps(a)
}

object syntax {
  object additiveSemigroup extends AdditiveSemigroupSyntax
}

object App {

  def main(args: Array[String]): Unit = {
    import syntax.additiveSemigroup._

    implicit def IntAlgebra[A]: AdditiveSemigroup[Map[Int, A]] = ???

    def res[A]: Map[Int, A] = {
      val a: Map[Int, A] = Map.empty
      val b: Map[Int, A] = Map.empty
      // Calls the operator on AdditiveSemigroupOps
      a ^ b
      // Calls the operator + on AdditiveSemigroupOps only in Scala 2
      // In Scala 3 tries to call `+` on Map
      a + b
    }
  }

}
0reactions
dwijnandcommented, Jun 29, 2021

No, the fix is in master so will be in 3.1.0 (and its pre-releases) - unless it were backported to the https://github.com/lampepfl/dotty/tree/release-3.0.1 branch.

Read more comments on GitHub >

github_iconTop Results From Across the Web

OPERATOR OVERLOADING
Some rules regarding operator overloading. • Overloading an operator cannot change its precedence. • Overloading an operator cannot change its associativity ...
Read more >
Overloading operators (C++ only) - IBM
You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class...
Read more >
Changes to the recommended sets for 3.0.0 #1423 - GitHub
I think this is a best practice. Organising overload signatures next to one another makes code a lot easier to understand. Verdict: in....
Read more >
Changes in Overload Resolution - Scala 3 - EPFL
Overload resolution in Scala 3 improves on Scala 2 in three ways. First, it takes all argument lists into account instead of just...
Read more >
Operator overloading - Wikipedia
In computer programming, operator overloading, sometimes termed operator ad hoc polymorphism, is a specific case of polymorphism, where different operators ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found