Monocle icon indicating copy to clipboard operation
Monocle copied to clipboard

Lenses can't be created for classes with private constructors for Scala 3

Open vadzim-marchanka opened this issue 1 year ago • 3 comments

Hello,

I've noticed that the code that compiles and works fine in scala 2 doesn't work for scala 3.

Scastie: Scala 2 -> https://scastie.scala-lang.org/FmuLKaM0TpmNvQ3xHdpUSg Scala 3 -> https://scastie.scala-lang.org/7FBOxnIPQbemh5TomJrUig

Code:

import monocle.syntax.all._

case class A private (field1: String, field2: String)
object A {
  def apply(field1: String, field2: String): A = new A(field1, field2)

  val copiedObject = A("1", "2").copy(field1 = "3")
  val modifiedObject = A("1", "2").focus(_.field1).replace("3")

  println(copiedObject)
  println(modifiedObject)
}

val copiedObject = A("1", "2").copy(field1 = "3") //compile error
val modifiedObject = A("1", "2").focus(_.field1).replace("3") //compile error
println(copiedObject)
println(modifiedObject) 

Error:

missing argument for parameter field2 of method copy in class A: (field1: String, field2: String): Playground.A
method copy cannot be accessed as a member of (from : Playground.A) from module class Playground$.

Could you please clarify whether it is expected behavior?

vadzim-marchanka avatar Feb 05 '24 14:02 vadzim-marchanka

I believe it is expected when you use private in your case class definition.

julien-truffaut avatar Feb 07 '24 15:02 julien-truffaut

Thank you for the response. Should the library behavior be the same for Scala 2 and 3? I expect that people migrating their codebase from Scala 2 to Scala 3 may face this issue.

vadzim-marchanka avatar Feb 26 '24 11:02 vadzim-marchanka

Ideally, yes it should be the same but I believe this is due to a change of semantic between Scala 2 and 3 for private case class constructors. So Monocle is just following the Scala language.

julien-truffaut avatar Feb 26 '24 11:02 julien-truffaut