gpt4 book ai didi

scheme - 将函数更改为 CPS 样式

转载 作者:行者123 更新时间:2023-12-04 02:56:43 26 4
gpt4 key购买 nike

我们被要求编写一个过程,当给定一个列表时,它将替换给定元素的第一次出现,并且只替换第一个,但要注意的是要以 CPS 风格编写。我们无法将其转换为 CPS 风格的书面程序,即给定成功-连续和失败-连续..

如果有人愿意尝试一下,我们将不胜感激:]

我们的程序(由答案慷慨提供 here ):

(define (replace-one list old new)
(cond ((pair? list)
(let ((next (replace-one (car list) old new)))
(cons next
(if (equal? next (car list)) ; changed?
(replace-one (cdr list) old new) ; no, recurse on rest
(cdr list))))) ; yes, done
((eq? list old) new)
(else list)))

最佳答案

已编辑

非常感谢@WillNess 指出并修复了一个隐藏在原始代码中的错误。这是基于他的 code (with stepwise derivation) 的更正实现, 评论并使 Racket 惯用:

(define (replace-one lst a b)
(let loop ([lst lst] ; input list
[f #f] ; have we made the first replacement?
[k (lambda (ls f) ls)]) ; continue with results: list and flag
(cond
(f ; replaced already:
(k lst f)) ; continue without changing anything
((empty? lst) ; empty list case
(k lst f)) ; go on with empty lst and flag as is
((not (pair? lst)) ; - none replaced yet - is this an atom?
(if (eq? lst a) ; is this the atom being searched?
(k b #t) ; replace, continue with updated flag
(k lst f))) ; no match, continue
(else ; is this a list?
(loop (first lst) ; process the `car` of `lst`
f ; according to flag's value, and then
(lambda (x f) ; accept resulting list and flag, and
(loop (rest lst) ; process the `cdr` of `lst`
f ; according to new value of flag,
(lambda (y f) ; getting the results from that, and then
(if f ; - if replacement was made -
(k ; continuing with new list, built from
(cons x y) ; results of processing the two branches,
f) ; and with new flag, or with
(k lst f)))))))))) ; the old list if nothing was changed

请注意,使用了单个成功延续(在上面的代码中称为 k),它接受两个 结果值:列表和标志。初始延续仅返回最终结果列表,并丢弃最终标志值。我们也可以返回标志,作为替换是否已经完成的指示。它在内部用于尽可能多地保留原始列表结构,与持久数据类型一样(如 in this answer 所示)。

最后,始终测试您的代码:

; fixed, this wasn't working correctly
(replace-one '((((1 2) 3 4) a) 6) 'a 'b)
=> '((((1 2) 3 4) b) 6)

(replace-one '(((-))) '- '+)
=> '(((+)))

(replace-one '((-) - b) '- '+)
=> '((+) - b)

(replace-one '(+ 1 2) '+ '-)
=> '(- 1 2)

(replace-one '((+) 1 2) '+ '-)
=> '((-) 1 2)

(replace-one '(1 2 ((+)) 3 4) '+ '-)
=> '(1 2 ((-)) 3 4)

(replace-one '() '+ '-)
=> '()

(replace-one '(1 2 ((((((+ 3 (+ 4 5)))))))) '+ '-)
=> '(1 2 ((((((- 3 (+ 4 5))))))))

关于scheme - 将函数更改为 CPS 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16550176/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com