【问题标题】:Calling lambda function directly直接调用 lambda 函数
【发布时间】:2015-03-19 13:30:17
【问题描述】:
(define a1 (list 1 2 3 4))
(define a2 (list + - * /))
(define a3 (list 5 6 7 8))
(map (lambda (x y z) (y x z))
a1 a2 a3)

如何不使用 map 直接调用这个 lambda 函数? 它所做的只是切换 y 和 x,使 (1 + 5) 变为 (+ 1 5)

【问题讨论】:

  • 这是什么语言?
  • Scheme (R5RS) ,抱歉没有说得更清楚。

标签: function lambda scheme


【解决方案1】:

您可以在不切换参数的情况下编写映射表达式:

(map (lambda (x y z) (x y z)) a2 a1 a3) ; ==> (6 -4 21 1/2)

请注意,我刚刚将参数的顺序切换为 map。 您可以通过将 lambda 括在括号中并添加参数来调用它。例如。

((lambda (op1 proc op2) (proc op1 op2)) + 2 3) ; ==> 5

map 函数只是对不同列表的每个元素执行此操作的一种方式。如果您知道列表的长度,您可以在不使用 lambda 的情况下获得相同的结果:

(list ((car a2) (car a1) (car a3))
      ((cadr a2) (cadr a1) (cadr a3))
      ((caddr a2) (caddr a1) (caddr a3))
      ((cadddr a2) (cadddr a1) (cadddr a3))) ; ==> (6 -4 21 1/2)

因为a2 的每个元素都是一个包装它的过程,括号中的参数适用于该过程。

一个 lambda 形式 (lambda (arg ...) body ...) 被评估并变成一个过程对象。当您定义命名过程时,会发生同样的情况,但名称会绑定到该过程对象。实际上。这三个版本没有区别:

;; version 1 using syntactic sugar define for procedures
(define (test x) (* x x))
(test 10) ;==> 100

;; version 2 defineing a variable to a procedure
(define test (lambda (x) (* x x)))
(test 10) ;==> 100

;; version 3 using the procdure directly
((lambda (x) (* x x)) 10) ; ==> 100

【讨论】:

    【解决方案2】:

    您可能知道,要在 Scheme 中调用函数,您需要编写 (f args),其中 f 是函数,args 是参数列表。无论f 是命名函数还是lambda,这都没有什么不同。所以要直接调用你的 lambda 函数,你会写:

    ;( -----------f------------ args- )
     ( (lambda (x y z) (y x z)) 1 + 2 )
    

    当然,这只是写(+ 1 2) 的一种相当复杂的方式,但是你去吧。

    【讨论】:

    • 如何使用我设置的定义来做到这一点?由于它们在列表中,我必须使用地图,但我试图避免这种情况。
    • @JohnNG 您是否在问如何在不使用map 的情况下执行map 的操作?如果是这样,您需要定义自己的递归函数(或者命名为 let)或使用折叠代替(除非您对 map 有相同的反对意见)。
    • 你会从 ((lambda (x y z) (y x z)) (car a1) (car a2) (car a3)) 这样的东西开始。
    猜你喜欢
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多