如果我正确理解你在做什么,p 是一个谓词,你根据这个拆分列表 l,用聚合函数 k 聚合你的两个结果列表;伪代码:
(split-by l p k) => (k {x in l | !p(x)} {x in l | p(x)})
替换let 时的问题是loop 函数是递归定义的。它的形式是:
(define (loop low high lst)
(cond
((null? lst) <some value>)
(<some predicate> (loop (cons (car lst) low) high (cdr lst)))
(else (loop low (cons (car lst) high) (cdr lst)))))
您绝对可以在您的函数中直接使用它,定义“内部”递归部分,但是如果没有let,则无法使用简单的lambda:函数需要引用自身 (因为它是递归的),您只能通过为其分配名称来做到这一点。 define 会这样做,let 会让你这样做,但无论你如何转动它,你都需要自我参照。如果您很聪明并通过延续:
(lambda (low high lst cont)
(cond
((null? lst) (agg high lst))
((pred? (car lst)) (cont low (cons (car lst) high) (cdr lst) cont))
(else (cont (cons (car lst) low) high (cdr lst) cont))))
您已经通过显式删除了该自引用,但是您传递的 cont 是什么?好吧,如果你通过 let 分配它,你就会有一个符号来引用它:
(define (split-by2 lst pred? agg)
(let ((f (lambda (low high lst cont)
(cond
((null? lst) (agg low high))
((pred? (car lst)) (cont low (cons (car lst) high) (cdr lst) cont))
(else (cont (cons (car lst) low) high (cdr lst) cont))))))
(f '() '() lst f)))
或者更简洁地使用define,它执行完全相同的操作(无需继续传递):
(define (split-by3 lst pred? agg)
(define (f low high lst)
(cond
((null? lst) (agg low high))
((pred? (car lst)) (f low (cons (car lst) high) (cdr lst)))
(else (f (cons (car lst) low) high (cdr lst)))))
(f '() '() lst))
所有的操作都类似:
(split-by '(1 2 3 4) (lambda (x) (> x 2)) list)
=> ((2 1) (4 3))
(split-by2 '(1 2 3 4) (lambda (x) (> x 2)) list)
=> ((2 1) (4 3))
(split-by3 '(1 2 3 4) (lambda (x) (> x 2)) list)
=> ((2 1) (4 3))
但是你不能为你的递归函数定义一个符号*。
至于您的示例为什么不起作用,它工作得非常好,只是它创建了一个 函数,将 function 作为参数(我称之为 @987654339 @ 以上)并应用您的逻辑给定该功能loop。由于您没有任何“循环”来传递它(因为您没有绑定它),它返回该函数并继续执行任何操作(此外,在您返回的lambda、low 和 @987654343 @ 未定义)。
* 这并不完全正确,因为您可以在您的 lambda 上使用combinators,但这会使它比应有的复杂得多:
(define Y
(lambda (h)
((lambda (x) (x x))
(lambda (g)
(h (lambda args (apply (g g) args)))))))
(define (split-ycomb lst pred? agg)
((Y
(lambda(f)
(lambda (low high l)
(cond
((null? l) (agg low high))
((pred? (car l)) (f low (cons (car l) high) (cdr l)))
(else (f (cons (car l) low) high (cdr l)))))))
'() '() lst))
或者对于更纯的 uglier 版本,带有内联组合器:
(define (split-ycomb2 lst pred? agg)
(((lambda (h)
((lambda (x) (x x))
(lambda (g)
(h (lambda args (apply (g g) args))))))
(lambda(f)
(lambda (low high l)
(cond
((null? l) (agg low high))
((pred? (car l)) (f low (cons (car l) high) (cdr l)))
(else (f (cons (car l) low) high (cdr l)))))))
'() '() lst))
按预期工作(感谢 lambda 层):
(split-ycomb '(1 2 3 4) (lambda (x) (> x 2)) list)
=> ((2 1) (4 3))
(split-ycomb2 '(1 2 3 4) (lambda (x) (> x 2)) list)
=> ((2 1) (4 3))