部分函数是一种仅对某些类型的值有效的函数。例如:
val root: PartialFunction[Double,Double] = {
case d if (d >= 0) => math.sqrt(d)
}
scala> root.isDefinedAt(-1)
res0: Boolean = false
scala> root(3)
res1: Double = 1.7320508075688772
当你有某些东西可以检查函数是否被定义时,这将是非常有用的。例如收集:
scala> List(0.5, -0.2, 4).collect(root)
res2: List[Double] = List(0.7071067811865476, 2.0)
这并不会帮助你将两个参数放置在你真正想要的位置。
相比之下,一个“部分应用的函数”是一个已经填充了一些参数的函数。
def add(i: Int, j: Int) = i + j
val add5 = add(_: Int,5)
现在您只需要一个参数——要加 5 的内容,而不是两个参数:
scala> add5(2)
res3: Int = 7
你可以从这个示例中了解如何使用它。
但是,如果你需要指定那两个参数,那么这个方法仍然不能实现。例如说你想使用 map
,并且你需要给它一个带有一个参数的函数,但你又想让它加上两个不同的东西。那么,你可以:
val addTupled = (add _).tupled
这将部分应用函数(实际上只是从方法中创建一个函数,因为没有填充任何内容),然后将单独的参数组合成元组。现在,您可以在需要单个参数的地方使用它(假设类型正确):
scala> List((1,2), (4,5), (3,8)).map(addTupled)
res4: List[Int] = List(3, 9, 11)
相比之下,柯里化则是另一种不同的方式;它将形如(A,B) => C
的函数转换为A => B => C
。也就是说,对于具有多个参数的函数,它将产生一系列函数,每个函数都需要一个参数并返回一个较短的链(您可以将其视为逐个部分应用一个参数)。
val addCurried = (add _).curried
scala> List(1,4,3).map(addCurried)
res5: List[Int => Int] = List(<function1>, <function1>, <function1>)
scala> res5.head(2) // is the first function, should add 1
res6: Int = 3
scala> res5.tail.head(5) // Second function should add 4
res7: Int = 9
scala> res5.last(8) // Third function should add 3
res8: Int = 11
arg1
将(arg1, arg2 => result)
转化为arg2 => result
。因为“偏函数”可能意味着完全不同的事情,在Scala中也使用相同的名称来表示那个意思(令人遗憾)。此外,你的问题是什么?虽然标题中有一个问号,但是你的帖子内容并不匹配。 - user395760Scala
中的PartialFunction
重命名为HalfFunction
:)。 - ssj