有什么快速方法可以用作(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库中了吗?
最佳答案
进行隐式转换是很危险的,出于同样的原因,(A) => B
不应继承自PartialFunction[A, B]
。即,PartialFunction的约定保证您可以安全地*在apply
返回isDefinedAt
的任何地方调用true
。 Function1的契约(Contract)不提供此类保证。
如果将隐式转换应用于未在所有地方定义的函数,则隐式转换将导致PartialFunction违反其约定。而是使用皮条客使转换明确:
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)
不会抛出异常,而仅仅是该异常是函数设计的一部分(应该记录在案)。关于来自具体功能的Scala PartialFunctions,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6834000/