5

有没有什么快速的方法可以用作一个具体的函数(例如,类型(A) => B)作为一个PartialFunction[A, B]?我所知道的最简洁的语法是:

(a: A) => a match { case obj => func(obj) }

是否有任何地方的隐式转换,例如:

implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] {

  def isDefinedAt(a: A) = true
  def apply(a: A) = func(a)

}

我想我只是写了我正在寻找的东西,但这是否已经存在于 Scala 库中?

4

2 回答 2

5

使用隐式转换执行此操作是危险的,原因与(A) => B不应继承自PartialFunction[A, B]. 也就是说,PartialFunction 的合约保证你可以安全地*调用apply任何isDefinedAt返回的地方true。Function1 的合约没有提供这样的保证。

如果您将隐式转换应用于未在任何地方定义的函数,您的隐式转换将导致违反其合同的 PartialFunction。相反,使用 pimp 使转换显式:

implicit def funcAsPartial[A, B](f: A => B) = new {
   /** only use if `f` is defined everywhere */
   def asPartial(): PartialFunction[A, B] = {
      case a => f(a)
   }

   def asPartial(isDefinedAt: A => Boolean): PartialFunction[A, B] = {
      case a if isDefinedAt(a) => f(a)
   }
}

// now you can write
val f = (i: Int) => i * i

val p = f.asPartial // defined on all integers
val p2 = f.asPartial(_ > 0) // defined only on positive integers

* 正如评论中所讨论的,这里的“安全”意味着什么可能并不完全清楚。我认为它的方式是 PartialFunction 在以下精确意义上显式声明其域:如果isDefinedAt为 value 返回 true x,则apply(x)可以以与函数作者的意图一致的方式进行评估。这并不意味着apply(x)不会抛出异常,而只是表示异常是函数设计的一部分(并且应该记录在案)。

于 2011-07-26T20:14:38.700 回答
0

不,几个月前我试图找到一个,结果我自己写了一个和你的基本一样的。

于 2011-07-26T17:31:01.150 回答