I have designed a case class that looks superficially like this:
case class Moo(foos: Seq[Foo], bar: Bar) {
require(foos.length == bar.baz.length)
...
}
This type will be consumed by a Java program, so I have created a convenient MooBuilder
to make it easier to populate the fields without having to explicitly instantiate Foo
s, Bar
s, and other types contained by these.
Currently MooBuilder
creates copies of objects when a field is set by its methods. I had read about lenses and wanted to give them a try to make the implementation cleaner.
So I installed quicklens and rewrote the builder, but came across this situation:
def addFooAndBaz(foo: Foo, baz: Baz): MooBuilder = {
moo = moo
.modify(_.foos) .using(_ :+ foo) /* (1) */
.modify(_.bar.baz).using(_ :+ baz) /* (2) */
this
}
Immediately after (1), moo.foos
has one more element than moo.bar.baz
, and this makes the require
call fail, so it never gets to (2) to fix the mismatch.
I know I can work around the issue by doing all the copying by hand (as I was doing before) or by removing the require
call in my case class's constructor. Still, I'd like to know: is there a standard way to solve the problem of doing several updates that make sense combined but not on their own, using lenses in Scala?