Scala PartialFunctions来自具体的

时间:2011-07-26 17:24:11

标签: scala partialfunction

有没有快速的方法可以作为具体功能(类型,比如(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库中了吗?

2 个答案:

答案 0 :(得分:5)

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

如果将PartidFunction应用于未定义的函数,则隐式转换将导致违反其合同的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为值x返回true,则可以通过以下方式评估apply(x)与函数作者的意图一致。那个暗示apply(x)不会抛出异常,而只是异常是函数设计的一部分(并且应该记录)。

答案 1 :(得分:0)

不,我几个月前试图找到一个,最后写了我自己的,与你的基本相同。