【问题标题】:cost of equality when using monocle/scalaz lenses使用单片眼镜/scalaz 镜片时的平等成本
【发布时间】:2017-06-06 10:21:34
【问题描述】:

我正在阅读有关 Diode 的信息,这让我想到了 Monocle / Scalaz 中的镜头:

如果我(有条件地)使用Monocle/Scalaz 镜头​​对深度嵌套数据结构的某些部分进行深度修改,并且想要比较是否有变化,是否需要进行深度比较,或者有没有办法使用引用相等来查看两个数据结构(有条件修改之前和之后)是否相同?

换句话说:

val f_new=modifyWithMonocleIfTheSunIsUp(f_old)

在数据结构的根 (f_old, f_new) 使用引用相等 (eq) 可以提高比较 f_new==f_old 的效率吗?

换句话说,

f_new==f_old 是否为真当且仅当f_new.eq(f_old) 为真? (Equation 1)

如果不是,为什么不呢?

如果没有,是否可以使 Equation 1 为 true ?怎么样?

【问题讨论】:

  • 就我极其有限的经验而言:如果您关心表演,请完全避免使用镜头。他们让你慢了很多。无论如何你提出的观点很有趣,等待答案。
  • 有什么选择?替代方案更好吗?
  • 我仍然没有很好的答案,但认为镜头只是一种语法糖的形式,开销很小,这是一种错误的信念,人们会被它的销售方式所引导。如果你需要处理大量的类和数据结构,那就太好了,但对于性能来说,它就不好了。但是,如果你不能利用并行性,那么整个不可变的方法是不利的。我对替代品很感兴趣,因为我可能处于与您类似的场景中,我想知道您的问题的答案以获取灵感并学习更有效地使用镜头或处理嵌套 DS
  • 我不认为 Haskell 中的镜头,例如,从性能的角度来看是不好的,实际上它们比替代品(手动模式匹配)更好。这解释了为什么:skillsmatter.com/skillscasts/…,所以 Scala 中的镜头可能也是如此,我认为它们并不比替代方案(即使用复制)差。
  • 顺便说一句,这是镜头的另一种替代品:stackoverflow.com/questions/41201045/…,使用 REF。

标签: scala scalaz lenses monocle-scala


【解决方案1】:

也许您可以使用modifyF 而不是modify 来返回Option,这样您就不必检查是否发生了变化。

例如:

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

【讨论】:

  • 感谢您的回答,有趣的方法。这个想法是在 any 两个Persons 之间实现快速相等比较。因此,如果有人随机给我两个Persons,那么只需要查看参考文献(使用eq),如果它们相等,那么我知道这两个人是相同的(无需进行深入的价值分析值比较)。使用这种方法,如果有人给我两个随机的Option[Person]-s(由程序在某个时间点生成 - 但我不知道何时何地),那么我无法确定它们是否相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 2012-03-14
  • 2012-01-08
相关资源
最近更新 更多