在Scheme中使用(使用lambda-foldr1)与(不使用lambda-foldr2)实现的foldr

在Scheme中使用(使用lambda-foldr1)与(不使用lambda-foldr2)实现的foldr,lambda,scheme,fold,Lambda,Scheme,Fold,我有两个版本的foldr实现 1) 用lambda实现foldr1 [foldr1 implementation] (define foldr1 (lambda (func lst end) (if (null? lst) end (func (car lst) (foldr1 func (cdr lst) end))))) 2) 无lambda的foldr2实现 [foldr2 implementation] (define (foldr2 fu

我有两个版本的foldr实现

1) 用lambda实现foldr1

[foldr1 implementation]
(define foldr1
  (lambda (func lst end)
    (if (null? lst)
    end
    (func (car lst)
        (foldr1 func (cdr lst) end)))))
2) 无lambda的foldr2实现

[foldr2 implementation]
 (define (foldr2 func end lst)
   (if (null? lst)
       end
       (func (car lst) 
         (foldr2 func end (cdr lst)))))
基本上相同的行为,但当使用foldr实现myFunc时,我有两个版本的myFunc

... myFunc2 using foldr2(foldr implemented without lambda)...
 (define (myFunc2 proced lst)                            
  (foldr2                                                     
   (lambda (acc x) (cons (proced acc) x))   
   '() 
   lst)
 )
=>工作正常

但是myFunc1(应与myFunc2的行为相同):


当使用用lambda实现的foldr1时,myFunc1到底有什么错误?

实际上,
foldr
“with
lambda
”和“without
lambda
”两个版本都是相同的,版本“without”只是“with”版本的语法糖,它们完全相同(除了参数的顺序发生了变化,但这没什么)

现在,
myFunc1
过程是另一回事。您以错误的顺序传递了最后两个参数,但这是您的问题中最小的一个-您编写的不是等效的,a
let
只返回最后一个表达式的值,在调用
foldr
时将精确计算一次,而ae> lambda是一个匿名过程,可以接收参数,并将在
foldr
中执行多次。更重要的是,
let
中的语法错误,无法编译。换句话说,这两行表示完全不同的内容和
let
版本(修复语法错误后)永远不会作为
foldr
的函数参数使用:

(lambda (acc x)  (cons (proced acc) x))    
(let ((acc x) x) (cons (proced acc)))

也许你会感到困惑,因为一个
let
表单可以用
lambda
来表示,正如演示的那样。但事实并非如此!你不能用
let
替换
lambda
…除非它恰好返回一个
lambda
,但这正是你想要避免的。实际上,两个
foldr
“with
lambda
”和“without
lambda
”的版本是相同的,版本“without”只是版本“with”的语法糖,它们是完全等效的(除了参数的顺序发生了变化,但这没什么)

现在,
myFunc1
过程是另一回事。您以错误的顺序传递了最后两个参数,但这是您的问题中最小的一个-您编写的不是等效的,a
let
只返回最后一个表达式的值,在调用
foldr
时将精确计算一次,而ae> lambda是一个匿名过程,可以接收参数,并将在
foldr
中执行多次。更重要的是,
let
中的语法错误,无法编译。换句话说,这两行表示完全不同的内容和
let
版本(修复语法错误后)永远不会作为
foldr
的函数参数使用:

(lambda (acc x)  (cons (proced acc) x))    
(let ((acc x) x) (cons (proced acc)))

也许你会感到困惑,因为一个
let
表单可以用
lambda
来表示,正如演示的那样。但事实并非如此!你不能用
let
替换
lambda
…除非它恰好返回一个
lambda
,但这正是你想要避免的。实际上,两个
foldr
“with
lambda
”和“without
lambda
”的版本是相同的,版本“without”只是版本“with”的语法糖,它们是完全等效的(除了参数的顺序发生了变化,但这没什么)

现在,
myFunc1
过程是另一回事。您以错误的顺序传递了最后两个参数,但这是您的问题中最小的一个-您编写的不是等效的,a
let
只返回最后一个表达式的值,在调用
foldr
时将精确计算一次,而ae> lambda是一个匿名过程,可以接收参数,并将在
foldr
中执行多次。更重要的是,
let
中的语法错误,无法编译。换句话说,这两行表示完全不同的内容和
let
版本(修复语法错误后)永远不会作为
foldr
的函数参数使用:

(lambda (acc x)  (cons (proced acc) x))    
(let ((acc x) x) (cons (proced acc)))

也许你会感到困惑,因为一个
let
表单可以用
lambda
来表示,正如演示的那样。但事实并非如此!你不能用
let
替换
lambda
…除非它恰好返回一个
lambda
,但这正是你想要避免的。实际上,两个
foldr
“with
lambda
”和“without
lambda
”的版本是相同的,版本“without”只是版本“with”的语法糖,它们是完全等效的(除了参数的顺序发生了变化,但这没什么)

现在,
myFunc1
过程是另一回事。您以错误的顺序传递了最后两个参数,但这是您的问题中最小的一个-您编写的不是等效的,a
let
只返回最后一个表达式的值,在调用
foldr
时将精确计算一次,而ae> lambda是一个匿名过程,可以接收参数,并将在
foldr
中执行多次。更重要的是,
let
中的语法错误,无法编译。换句话说,这两行表示完全不同的内容和
let
版本(修复语法错误后)永远不会作为
foldr
的函数参数使用:

(lambda (acc x)  (cons (proced acc) x))    
(let ((acc x) x) (cons (proced acc)))
也许你会感到困惑,因为一个
let
形式可以用
lambda
来表示,正如所演示的。但事实并非如此!你不能用
let
替换
lambda
…除非发生这种情况
(define sqrt (lambda (x) (* x x)))
(define (sqrt x) (* x x))
(sqrt 10)                  ; ==> 100

(define list (lambda l l))
(define (list . l) l)
(list 1 2 3 4)             ; ==> (1 2 3 4)

;; notice its fold1 as in number 1, not lowercase L
(define fold1 
  (lambda (fun acc lst)
    (let loop ((acc acc) (lst lst))
      (if (null? lst)
          acc
          (loop (fun (car lst) acc) (cdr lst))))))

(define (fold1 fun acc lst)
    (let loop ((acc acc) (lst lst))
      (if (null? lst)
          acc
          (loop (fun (car lst) acc) (cdr lst)))))

(fold1 cons '() '(1 2 3 4))    ; ==> (4 3 2 1)
(foldr (let ()
         (define (my-add a b) (+ a b)) ; remember this is  too
         my-add) ; return my-add
       0 
       '(1 2 3 4 5)) ; ==> 15
(foldr (lambda (a b) (+ a b)) ; PS: just + would suffice
       0 
       '(1 2 3 4 5)) ; ==> 15