jhegedus
jhegedus

Reputation: 20653

cost of equality when using monocle/scalaz lenses

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

Answers (1)

Peter Neyens
Peter Neyens

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

Related Questions