昨天我在 SO 上发现了 scala mapConserve:scala List map vs mapConserve

我的问题是,什么时候有人想使用这种方法?提供的示例将 mapConserve 与标识函数一起使用,我看不到它的用例......

编辑:GitHub 进行了快速搜索,发现了 816 个使用 mapConserve 的 Scala 代码块。其中许多(至少 3 页)是以下代码块:

  def checkStackOverflow() = {
    var xs: List[String] = Nil
    for (i <- 0 until 250000)
        xs = "X" :: xs

    val lowers = xs.mapConserve(_.toLowerCase)
    assert(xs.mapConserve(x => x) eq xs)
  }

最佳答案

这个问题激起了我的兴趣,所以我浏览了 Scala 代码库并查看了 mapConserves() 的实际用途。

在几个地方弹出的一个是:如果参数是部分函数,​​则轻松跟踪 map 操作是否进行了实际更改(通过简单的引用检查),例如 Erasure 中的这个示例:

def squashBoxed(tp: Type): Type = tp.dealiasWiden match {
  case t @ RefinedType(parents, decls) =>
    val parents1 = parents mapConserve squashBoxed
    if (parents1 eq parents) tp
    else RefinedType(parents1, decls)
  // ...

如果没有执行实际更改,则代码可以防止之后运行某种昂贵的操作。
具有常规 map() 的该用例的替代方案是..
  • ..更昂贵[1]:迭代两个列表并在之后比较它们的元素
  • ..notfunctional:在传递给 map() 的部分函数中跟踪它是否通过改变某种外部标志进行了更改 -> 副作用,不纯,不是函数式的做事方式;也恕我直言,总体上非常丑陋

  • [1] 这在给定情况下是否重要当然取决于优化之前的怀疑措施。通常,该方法现在似乎较少使用,这可能是一个通常不重要的赠品。

    关于Scala mapConserve 用例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39613567/

    10-12 13:31