scala - 在 Scala 中使用部分函数 - 它是如何工作的?

标签 scala functional-programming jvm-languages

我是 Scala 新手,我正在使用 2.9.1,并且我正在尝试了解如何使用部分函数。我对柯里化(Currying)函数有基本的了解,并且我知道部分函数有点像柯里化(Currying)函数,它们只是 2nary 或类似的函数。正如你所见,我对此有点陌生。

似乎在某些情况下(例如 XML 过滤),能够实现部分功能将非常有利,因此我希望更好地了解如何使用它们。

我有一个使用 RewriteRule 结构的函数,但我需要它使用两个参数,而 RewriteRule 结构只接受一个或部分函数。我认为这是我认为有用的案例之一。

欢迎任何建议、链接、智慧之言等!

到目前为止的答案非常好,并且消除了我的一些基本误解。我认为他们也解释了我在哪里挣扎 - 我认为也许发布一个更具体的新问题会有所帮助,所以我也会这样做。

最佳答案

部分函数是仅对您可能传递给它的类型的值的子集有效的函数。例如:

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)   // List of _only roots which are defined_
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)

相比之下,柯里化(Currying)又有所不同;它将 (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

关于scala - 在 Scala 中使用部分函数 - 它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8650549/

相关文章:

scala - Cassandra 连接器 Apache Spark : local class incompatible

functional-programming - 在 Racket 中编写缓存函数

java - java中有什么好的持久集合框架?

java - Java平台的投资数据

groovy - 格鲁维怎么了?

scala - 比较 Scala Spark 中的两个数组列

scala - Slick 的日志记录选项

grails - Grails应用程序中Groovy代码的编译

scala - 可选元组到选项元组

haskell - 在 Haskell 中生成笛卡尔积