简体   繁体   English

球拍中的Lambda解释

[英]Lambda in Racket Explained

I am trying to understand lambda use in racket and I am still unclear. 我试图理解在球拍中使用lambda,我仍然不清楚。 I get that they are unnamed (anonymous) functions but why is that good? 我知道他们是无名(匿名)功能,但为什么这么好? I need to access my functions from other functions so how would I call them??? 我需要从其他函数访问我的函数,所以我怎么称呼它们? Please explain the small program below and why using lambda is better? 请解释下面的小程序,为什么使用lambda更好? Thank you. 谢谢。

; why is this better than below???
(define test
  (lambda (x)
    (lambda (y)
      (+ x y))))

(define add27
  (test 27))

; what's wrong with this???
(define (addTest x)
  (+ x 27))

> (add27 2)
29
> (addTest 2)
29

In Racket (and other functional programming languages) lambda s are very useful, when you want to pass an in-line, one-shot function as a parameter without defining it first. 在Racket(和其他函数式编程语言)中,当你想要将一个内联的单次触发函数作为参数传递而不首先定义它时, lambda非常有用。 For example, suppose that we want to square a list of numbers. 例如,假设我们想要对数字列表进行平方。 We can go the long way and define a square function first, and then use map : 我们可以先走很长的路,先定义一个square函数,然后使用map

(define (square x)
  (* x x))

(map square '(1 2 3 4 5))
=> '(1 4 9 16 25)

… Or we can simply pass a lambda , like this: ...或者我们可以简单地传递一个lambda ,如下所示:

(map (lambda (x) (* x x))
     '(1 2 3 4 5))

=> '(1 4 9 16 25)

As you can see, there exist cases where we don't need to refer to a function's name. 如您所见,存在我们不需要引用函数名称的情况。 Of course, if the procedure represented by the lambda is going to be reused in several parts, or if it's recursive then it makes sense to give it a name (so it's no longer anonymous): 当然,如果由lambda表示的过程将在几个部分中重用,或者如果它是递归的,那么为它命名是有意义的(因此它不再是匿名的):

(define square
  (lambda (x) (* x x)))

The above is equivalent to the first definition of square at the beginning. 以上等同于开头的第一个square定义。 In fact, the first definition is just syntactic sugar to define a function, but in the end all functions are lambdas ! 实际上,第一个定义只是定义函数的语法糖,但最后所有函数都是lambdas

Now let's see your example. 现在让我们看看你的例子吧。 Here we are using a lambda in a slightly different fashion, and also exemplifies why they're useful - we're not only defining a function, but returning a function as well: 这里我们以略微不同的方式使用lambda ,并举例说明它们为什么有用 - 我们不仅定义了一个函数,还返回了一个函数:

(define test
  (lambda (x)
    (lambda (y)
      (+ x y))))

Perhaps it'll be a bit clearer if we write it like this (it's equivalent, for the reasons mentioned above): 也许如果我们这样写它会更清楚一点(由于上面提到的原因它是等价的):

(define (test x)
  (lambda (y)
    (+ x y)))

Or even shorter - in Racket we can also use this syntax for the same purpose: 甚至更短 - 在Racket中我们也可以将此语法用于同一目的:

(define ((test x) y)
  (+ x y))

It's not that this is a better (or worse ) way to define a function - it's a different thing! 并不是说这是一种更好 (或更糟 )的定义功能的方式 - 这是另一回事! we're defining a procedure called test , that receives as parameter x and returns as a result a new anonymous function, that in turn will receive as parameter y . 我们定义了一个名为test的过程,它接收为参数x并返回一个新的匿名函数,该函数又将作为参数y接收。 Now, in these lines: 现在,在这些方面:

(define add27
  (test 27))

… we're calling test with an x value of 27 , which returns the anonymous function, and we name that function add27 . ......我们调用testx的值27 ,返回匿名函数,我们名称功能add27 Remember the lambda that received as parameter y ? 还记得作为参数y收到的lambda吗? now that lambda has been named add27 - and this is an example of currying . 现在lambda被命名为add27 - 这是currying的一个例子。 Think of it: test is a function that is used for generating functions that add a fixed value x to a given parameter y , that explains why this works: 想一想: test是一个函数,用于生成向给定参数y添加固定值x的函数,这解释了为什么这样可行:

(add27 2)
=> 29

On the other hand, this function will always add 27 to its parameter with no way to change it: 另一方面,此函数将始终为其参数添加27 ,无法更改它:

(define (addTest x)
  (+ x 27))

(addTest 2)
=> 29

You see the difference? 你看到了区别? test allows us to generate new functions that add an arbitrary value, whereas addTest always adds a fixed value, 27 . test允许我们生成添加任意值的新函数,而addTest总是添加一个固定值27 What if you wanted to add say, 100 ? 如果你想加100怎么办? using test this is simple: 使用test这很简单:

(define add100 (test 100))

But addTest can't be changed, we would need to write a new function: 但是addTest无法更改,我们需要编写一个新函数:

(define (addTest100 x)
  (+ x 100))

I hope this clarifies things, feel free to ask in the comments any additional questions about my answer. 我希望这可以澄清一些事情,随时可以在评论中询问有关我答案的任何其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM