匿名 Scala 函数语法 [英] Anonymous Scala function syntax

查看:21
本文介绍了匿名 Scala 函数语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习更多关于 Scala 的知识,但我在理解 http://www.scala-lang.org/node/135.我复制了下面的整个代码块:

I'm learning more about Scala, and I'm having a little trouble understanding the example of anonymous functions in http://www.scala-lang.org/node/135. I've copied the entire code block below:

object CurryTest extends Application {
    def filter(xs: List[Int], p: Int => Boolean): List[Int] =
        if (xs.isEmpty) xs
        else if (p(xs.head)) xs.head :: filter(xs.tail, p)
        else filter(xs.tail, p)

    def modN(n: Int)(x: Int) = ((x % n) == 0)

    val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
    println(filter(nums, modN(2)))
    println(filter(nums, modN(3)))
}

我对 modN 函数的应用感到困惑

I'm confused with the application of the modN function

def modN(n: Int)(x: Int) = ((x % n) == 0)

在这个例子中,它是用一个参数调用的

In the example, it's called with one argument

modN(2) and modN(3)

modN(n: Int)(x: Int) 的语法是什么意思?

What does the syntax of modN(n: Int)(x: Int) mean?

因为它是用一个参数调用的,所以我假设它们不是两个参数,但我真的无法弄清楚 mod 函数如何使用来自 nums 的值.

Since it's called with one argument, I'm assuming they're not both arguments, but I can't really figure out how the values from nums get used by the mod function.

推荐答案

这是函数式编程中的一个有趣的东西,叫做 咖喱.基本上,Moses Schönfinkel 和后来的 Haskell Curry(尽管 Schonfinkeling 听起来很奇怪……)提出了调用多个参数的函数的想法,比如 f(x,y) 与链相同调用 {g(x)}(y)g(x)(y) 其中 g 是产生另一个函数的函数它的输出.

This is a fun thing in functional programming called currying. Basically Moses Schönfinkel and latter Haskell Curry (Schonfinkeling would sound weird though...) came up with the idea that calling a function of multiple arguments, say f(x,y) is the same as the chain of calls {g(x)}(y) or g(x)(y) where g is a function that produces another function as its output.

以函数f(x: Int, y: Int) = x + y为例.正如预期的那样,对 f(2,3) 的调用将产生 5.但是当我们对这个函数进行柯里化时会发生什么 - 将它重新定义为 f(x:Int)(y: Int) 并将其称为 f(2)(3).第一次调用 f(2) 产生一个函数,它接受一个整数 y 并将 2 添加到它 -> 因此 f(2) 的类型为 Int =>Int 等价于函数 g(y) = 2 + y.第二次调用 f(2)(3) 使用参数 3 调用新生成的函数 g,因此计算结果为 5,正如预期的那样.

As an example, take the function f(x: Int, y: Int) = x + y. A call to f(2,3) would produce 5, as expected. But what happens when we curry this function - redefine it as f(x:Int)(y: Int)and call it as f(2)(3). The first call, f(2) produces a function taking an integer y and adding 2 to it -> therefore f(2) has type Int => Int and is equivalent to the function g(y) = 2 + y. The second call f(2)(3) calls the newly produced function g with the argument 3, therefore evaluating to 5, as expected.

另一种查看它的方法是逐步完成f(2)(3) 的归约(函数式程序员称之为beta 归约——它就像逐行逐行的函数式方法)调用(注意,以下不是真正有效的 Scala 语法).

Another way to view it is by stepping through the reduction (functional programmers call this beta-reduction - it's like the functional way of stepping line by line) of the f(2)(3) call (note, the following is not really valid Scala syntax).

f(2)(3)         // Same as x => {y => x + y}
 | 
{y => 2 + y}(3) // The x in f gets replaced by 2
       |
     2 + 3      // The y gets replaced by 3
       |
       5

所以,在讲完所有这些之后,f(x)(y) 可以被看作只是下面的 lambda 表达式 (x: Int) =>{(y: Int) =>x + y} - 这是有效的 Scala.

So, after all this talk, f(x)(y) can be viewed as just the following lambda expression (x: Int) => {(y: Int) => x + y} - which is valid Scala.

我希望这一切都有意义 - 我试图给出一些为什么modN(3)调用有意义的背景:)

I hope this all makes sense - I tried to give a bit of a background of why the modN(3) call makes sense :)

这篇关于匿名 Scala 函数语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆