PartialFunction 的 isDefined 和 Apply 中都发生代价高昂的计算

2023-11-27

很可能要知道某个函数是否在某个时刻被定义,必须完成计算其值的重要部分。在一个PartialFunction,执行时isDefined and apply,两种方法都必须这样做。这份普通的工作成本高怎么办?

有可能缓存它的结果,希望在isDefined之后调用apply。绝对是丑陋的。

我常常希望PartialFunction[A,B]将会Function[A, Option[B]],这显然是同构的。或者,也许还有另一种方法PartialFunction, say applyOption(a: A): Option[B]。对于某些 mixins,实现者可以选择实现 isDefined 和 apply 或 applyOption。或者所有这些都是为了安全起见,性能明智。测试的客户isDefined鼓励在调用 apply 之前使用applyOption反而。

然而,事实并非如此。库中的一些主要方法,其中collect在集合中需要一个PartialFunction。是否有一种干净(或不太干净)的方法来避免为 isDefined 和 apply 之间重复的计算付费?

还有,就是applyOption(a: A): Option[B]方法合理吗?在未来的版本中添加它听起来可行吗?值得吗?


为什么缓存会出现这样的问题?在大多数情况下,您有本地计算,因此只要为缓存编写一个包装器,就不必担心它。我的实用程序库中有以下代码:

  class DroppedFunction[-A,+B](f: A => Option[B]) extends PartialFunction[A,B] {
    private[this] var tested = false
    private[this] var arg: A = _
    private[this] var ans: Option[B] = None
    private[this] def cache(a: A) {
      if (!tested || a != arg) {
        tested = true
        arg = a
        ans = f(a)
      }
    }        
    def isDefinedAt(a: A) = {
      cache(a)
      ans.isDefined
    }
    def apply(a: A) = {
      cache(a)
      ans.get
    }
  }
  class DroppableFunction[A,B](f: A => Option[B]) {
    def drop = new DroppedFunction(f)
  }
  implicit def function_is_droppable[A,B](f: A => Option[B]) = new DroppableFunction(f)

然后如果我有一个昂贵的计算,我会编写一个函数方法A => Option[B]并做类似的事情(f _).drop将其用于收集或其他用途。 (如果您想内联执行此操作,您可以创建一个方法,该方法需要A=>Option[B]并返回部分函数。)

(相反的变换——从PartialFunction to A => Option[B]--称为提升,因此称为“下降”;我认为“unlift”是一个更广泛使用的相反操作术语。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PartialFunction 的 isDefined 和 Apply 中都发生代价高昂的计算 的相关文章

  • 在案例类中重载 unapply 方法:scala

    考虑下面的代码 case class User id Int name String object User def unapply str String Some User 0 str Scala 抱怨 错误 无法解析重载未应用 案例类
  • 根据 Slick 中的 Id 选择单行

    我想根据 Id 查询用户的一行 我有以下虚拟代码 case class User id Option Int name String object Users extends Table User user def id column In
  • Scala:如何转义文字中的反引号?

    Scala 中的文字允许将标识符定义为这样answer https stackoverflow com a 6576663 5826349描述 有没有办法在文字中转义反引号 做类似的事情 val hello world hello worl
  • 为什么 Scala 选项的 foreach 比 get 更好?

    为什么使用foreach map flatMap等被认为比使用更好get对于 Scala 选项 如果我使用isEmpty我可以打电话get安全 好吧 这又回到了 告诉 不要问 考虑这两行 if opt isDefined println o
  • scala 贷款模式,可选函数参数

    我有一个贷款模式 该模式应用函数 n 次 其中 i 是递增变量 偶尔 我希望传入的函数能够访问 i 但我不想要求传入的所有函数都需要定义一个参数来接受 i 下面的例子 def withLoaner n Int gt op Int gt St
  • 理解无形状的“单态”示例

    The 无形特征概述 https github com milessabin shapeless wiki Feature overview 3a shapeless 2 0 0显示以下示例 import poly choose is a
  • Scala API 2.10.*:Function2.and然后发生了什么?

    我正在阅读 Joshua Suereth 所著的 Scala in Depth 我购买这本书是为了了解作者的明确能力 我在第 3 页上 在出现一堆拼写错误和不连贯的格式之后 好吧 我已经开始容忍这些错误 我偶然发现了以下示例 该示例涉及解决
  • 如何在scala中运行时查找类参数数据类型

    import scala reflect runtime universe import scala reflect runtime universe def getType T TypeTag obj T typeOf T case cl
  • 使方法真正内联

    我伪造了一个简单的例子来检查 inline注释行为 import scala annotation tailrec object InlineTest extends App inline private def corec x Int I
  • 在 sbt 中定义自定义测试配置

    我需要在 sbt 中定义一个运行测试的自定义测试配置 但需要一些额外的设置 我一直在环顾四周 试图弄清楚如何做到这一点 但我似乎无法做到这一点 我想做的是这样的 gt test这将运行正常的测试任务并且 gt pipelinetest这与测
  • 如何找出哪个依赖项导致特定库被下载?

    运行我的 SBT 项目时 控制台输出中有一行 info downloading http repository nexus content groups public org jboss netty netty 3 2 3 Final ne
  • 如何将枚举绑定到 playframework 表单?

    我有一个以下形式的枚举 object MatchFilterType extends Enumeration type MatchFilterType Value val gt Value gt val lt Value lt val eq
  • 测试期权价值的更好方法?

    我经常发现自己Option T 对于某些类型T并希望根据某个值来测试期权的价值 例如 val opt Some oxbow if opt isDefined opt get lakes do something 以下代码是等效的 并且不需要
  • 从 Monoids 的 HList 类型派生 0 的 HList

    我正在学习 Shapeless 目前我正在尝试创建一个执行以下操作的函数 给定一个类型HList它返回HList of Nones 与Option对应于给定的类型HList type 例如 create String Int HNil re
  • 方法返回类型的类型推断

    当存在显式方法时 为什么 Scala 无法推断方法的返回类型return方法中使用的语句 例如 为什么下面的代码可以编译 object Main def who 5 def main args Array String println wh
  • 通过Listener获取Spark thrift服务器查询中读取的行数

    我正在尝试为我们的 ST 服务器构建一个监控系统 到目前为止 诸如记录查询 检索的行 红色和花费的时间之类的事情都很好 我已经实现了一个自定义侦听器 我能够毫无问题地检索查询和时间 侦听SparkListenerSQLExecutionSt
  • 使用值类参数的 Mockito 存根方法失败并出现 NullPointerException

    使用类型化值类作为 ID 是 Scala 中的常见模式 然而 在存根以值类作为参数的方法时 Mockito 似乎遇到了问题 在下面的示例中 第一个具有实际值的存根工作得很好 但第二个使用参数匹配器的存根会抛出 NullPointerExce
  • 如何在不进行硬编码的情况下使用 Cake 模式进行依赖注入?

    我刚刚阅读并享受蛋糕图案文章 http jonasboner com real world scala dependency injection di 然而 在我看来 使用依赖项注入的关键原因之一是您可以改变 XML 文件或命令行参数所使用
  • 我需要比较两个数据帧以进行类型验证并发送非零值作为输出

    我正在比较两个数据帧 基本上 这些是两个不同数据源的模式 一个来自 hive 另一个来自 SAS9 2 我需要验证两个数据源的结构 因此我将模式转换为两个数据帧 它们是 SAS 架构将采用以下格式 scala gt metadata sho
  • 将数组中的值提取到元组中

    有没有一种简单的方法可以将列表的值提取到 Scala 中的元组中 基本上是这样的 15 8 split map toInt mkTuple 15 8 或者我可以采取其他方式 val x y 15 8 split map toInt 如果你把

随机推荐