Reputation: 20653
I was reading about Diode, and it made me think about lenses in Monocle / Scalaz:
If I (conditionally) modify deeply some part of a deeply nested data-structure using Monocle/Scalaz lens and want to compare if there was a change, is there a need to do a deep comparison, or is there a way to use reference equality to see if the two data-structures (before conditionaly modification and after) are the same ?
In other words:
val f_new=modifyWithMonocleIfTheSunIsUp(f_old)
Can the comparison f_new==f_old
be made efficient using reference equality (eq
) at the root (f_old
, f_new
) of the data-structure ?
In other words,
is it true that f_new==f_old
is true if and only if f_new.eq(f_old)
is true ? (Equation 1)
If not, why not ?
If not, is it possible to make Equation 1
true ? How ?
Upvotes: 3
Views: 321
Reputation: 9820
Maybe you can use modifyF
instead of modify
to return an Option
so you don't have to check if something has changed.
For example :
import monocle.Lens
import monocle.macros.GenLens
import scalaz.std.option._
case class Person(name: String, address: Address)
case class Address(street: String, number: Int)
val addressL: Lens[Person, Address] = GenLens[Person](_.address)
val streetL: Lens[Address, String] = GenLens[Address](_.street)
val changePersonsStreet: Person => Option[Person] =
(addressL composeLens streetL).modifyF[Option] { street =>
// only change street name if first letter comes before 'N'
street.headOption.filter(_.toString.capitalize < "N").map(_ => "New Street")
// or any other condition
// if (theSunIsUp) Some("changed street name") else None
} _
val alice = Person("Alice", Address("Main Street", 1))
val alice2: Option[Person] = changePersonsStreet(alice)
// Some(Person(Alice,Address(New Street,1)))
// -> modified, no need to check
val alice3 = alice2.flatMap(changePersonsStreet)
// None
// -> not modified
Upvotes: 1