我试图在球拍中使用高阶函数编写一个函数,它使用两个符号,sym1和sym2以及一个符号列表,并返回列表,每个sym1和sym2实例都被交换。
我想出了如何使用累加器函数执行此操作,但我只是好奇这对于高阶函数是如何工作的,因为它们需要一个参数函数,而不是单个变量。谢谢!
(define (swapper/ho str1 str2 los)
(local
[(define (swapper-acc los acc)
(cond
[(empty? los) acc]
[(symbol=? str1 (first los))
(swapper-acc (rest los) (append acc (list str2)))]
[(symbol=? str2 (first los))
(swapper-acc (rest los) (append acc (list str1)))]
[else
(swapper-acc (rest los) (append acc (list (first los))))]))]
(swapper-acc los empty)))
答案 0 :(得分:0)
对于具有更高阶函数的解决方案,请不要再看了 - foldr
可以解决这个问题:
(define (swapper/ho str1 str2 los)
(foldr (lambda (e acc)
(cond ((symbol=? e str1) (cons str2 acc))
((symbol=? e str2) (cons str1 acc))
(else (cons e acc))))
'()
los))
此外,您的解决方案可以改进 - 在构建输出列表时使用append
是一个坏主意(效率非常低),请改用cons
。实际上,这正是您使用通常的模板递归遍历列表所解决的问题,您甚至不需要本地帮助器或累加器:
(define (swapper/ho str1 str2 los)
(cond ((empty? los)
empty)
((symbol=? str1 (first los))
(cons str2 (swapper/ho str1 str2 (rest los))))
((symbol=? str2 (first los))
(cons str1 (swapper/ho str1 str2 (rest los))))
(else
(cons (first los) (swapper/ho str1 str2 (rest los))))))
例如:
(swapper/ho 'x 'y '(a x b c y d x y))
=> '(a y b c x d y x)