在PartDefine的定义和应用中都会出现代价高昂的计算

Did*_*ont 8 scala

很有可能要知道函数是否在某个时刻定义,计算其价值的重要部分必须完成.在PartialFunction,在实现时isDefinedapply,这两种方法将不得不这样做.怎么办这个常见的工作成本很高?

有可能缓存其结果,希望在isDefined之后调用apply.绝对丑陋.

我经常希望那PartialFunction[A,B]Function[A, Option[B]],这显然是同构的.或许,可能还有另一种方法PartialFunction,比方说applyOption(a: A): Option[B].对于一些mixins,实现者可以选择实现isDefined和apply或applyOption.或者所有这些都是安全的,性能明智.isDefined在呼叫申请之前进行测试的客户将被鼓励使用applyOption.

但事实并非如此.库中的一些主要方法,其中包括collect集合中的一些PartialFunction.是否有一种干净(或不那么干净)的方式来避免支付isDefined和apply之间重复的计算?

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

Rex*_*err 4

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

  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)
Run Code Online (Sandbox Code Playgroud)

然后,如果我有一个昂贵的计算,我会编写一个函数方法A => Option[B]并执行诸如(f _).drop在收集或其他操作中使用它之类的操作。(如果您想内联执行此操作,您可以创建一个接受A=>Option[B]并返回部分函数的方法。)

(相反的转换——从PartialFunctionA => Option[B]——称为提升,因此称为“下降”;我认为“取消提升”是相反操作的更广泛使用的术语。)