如果我正确理解你在做什么,是一个谓词,你根据这个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)))))
您绝对可以直接在您的函数中使用它,定义“内部”递归部分,但是如果没有,就不能简单地使用lambda
它let
:函数需要引用自身(因为它是递归的),您只能通过分配它来做到这一点一个名字。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)))
或者更简洁地使用 a 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 ,将一个function(我在上面调用过)作为参数并在给定 functioncont
的情况下应用您的逻辑。由于您没有任何“循环”来传递它(因为您没有绑定它),它返回该函数并继续不做任何事情(此外,在您的返回中,并且未定义)。loop
lambda
low
high
* 这并不完全正确,因为您可以在 lambda 上使用组合器,但这会使它变得比应有的复杂得多:
(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))
或者对于更丑陋的更纯粹的版本,使用内联组合器:
(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))
哪个按预期工作(感谢 lambdas 层):
(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))