gpt4 book ai didi

foreach - for-each 中的方案延续

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

我目前正在我大学的一门类(class)中学习 Scheme,在看一些练习时我被困在了这个特定的练习上。教授还没有回复我以前的邮件,所以我有更多机会在这里更快地收到回复。

给定这段代码

(define (list-iter-cc lst)
(call/cc
(lambda (return)
(for-each
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)
'end)))

我必须用它来编写 iter语法为

的宏
(iter <a variable symbol> in <a list> <code>)

例子:

(iter x in '(1 2 3) 
(display x)
(newline))

因为我看不懂list-iter-cc我去看了解决方案,我也不明白。解决方案:

(define-syntax iter2
(syntax-rules (-> in)
((_ var in lst code ...)
(let loop ((head (list-iter-cc lst)))
(unless (eq? head 'end)
(let ((var (car head)))
code ...
(loop ((cdr head)))))))))

为了解开宏,我尝试编写以下内容

> (define head (list-iter-cc '(1 2 3 4)))
> head
'(1 . #<continuation>)
> (let ( (var (car head))) (display var))
1
> (define head2 (cdr head))
> (let ( (var2 (car head2)) ) (display var2))
Xxx X car: contract violation
expected: pair?
given: #<continuation>
>

这正是我所想的。

list-iter-cc在第一个 lambda 中 for-each 的第一次迭代中调用的返回延续,返回 cons x next-step . x是列表的第一个元素,next-step是延续。

1). next-step的内容是什么? for-each 的以下迭代?它如何评估为 'end在最后一次迭代之后?

2).假设在宏中 head (list-iter-cc lst)'(1 . #<continuation>)汽车1它得到显示,但在遍历其 cdr 之后,var (car head)将是延续的汽车!它怎么可能评估为2然后 3然后 'end ,为什么在我尝试编写以理解它的代码中没有发生这种情况?

任何帮助将不胜感激,尤其是可以指导我一步一步的帮助。

最佳答案

我们可以将其重写为

(define list-iter-cc 
(lambda (lst)
(call/cc
(lambda (return)
(for-each
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)
'end))))

所以它是一个 lambda 函数,带有一个名为 lst 的参数.调用此函数时,lst像往常一样设置为保存函数调用的实际参数。然后,call/cc设置名为 return 的延续持有当前的延续......这是什么?此时,下一步要做的只是返回一个值给list-iter-cc。的来电者。

这意味着,调用 (return a)将返回 a 的值立即到list-iter-cc的调用者,就好像函数 list-iter-cc完成了它的计算。

现在,

        (for-each               
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)

已输入。它为列表中的每个元素调用其 lambda 参数 lst ,因此得名 x .

所以,对于拳头xlst , 怎么了?

              (call/cc (lambda (next-step)
(return (cons x next-step))))

被调用。 IE。它设置了next-step保持当前延续并返回整个函数list-iter-cc立刻!

它返回什么?这对 (x . <next-step>) . 什么调用(next-step)是什么意思? ?意思是返回到for-each的正文中,这将继续到 lst 中的下一个元素, 如果有的话。如果不是,for-each的循环体退出,'end 通常作为函数 list-iter-cc 的最后一个表达式的值返回, 这样就完成了它的计算!

那么,我们该如何使用它呢?例如,像这样:

(define (qq lst)
(let ([a ;; <<= ; control returns here
(list-iter-cc lst)])
(unless (eq? a 'end) ; if it's not past-last-element
(let ([val (car a)]) ; take the actual value
(display val) ; use it
(newline)
((cdr a)))))) ; run the `next-step` continuation

当在 (cdr a) 中继续时运行时,控件跳回到list-iter-cc的调用站点。请记住,“下一步要做的事情”是“只是向 list-iter-cc 的调用者返回一个值”?外层let然后使用列表中的下一个值重新输入的主体。

然后需要将其转换为宏,这应该很简单。

我注意到你的教授在那里使用了命名循环,宏调用了(loop ((cdr a))) .虽然延续不返回它的值,因此 loop 的下一次迭代未输入 因为调用了 loop 。控件 jumps 作为延续的一部分,如我的示例函数所示(当我在 DrRacket 中测试它时,它起作用了)。


更新关于你的成绩单,head2已经是 #<continuation> , 它没有 car – 它不是 pair? .相反,请参阅以下内容:

> (define head #| <<= |# (list-iter-cc '(1 2 3 4)))   ; control returns here
> head
'(1 . #<continuation>)
> (let ( (var (car head))) (display var)) ; your code
1
> ((cdr head)) ; this is how we run it!
> head
'(2 . #<continuation>)
>

什么?你看到刚刚发生的事情了吗? head重新定义了!再一次,

> ((cdr head))
> head
'(3 . #<continuation>)
>

为什么?因为运行延续意味着控制返回到它的调用点——在这里,这意味着“定义一个变量 head 来保存提供的值,然后返回到 REPL”

关于foreach - for-each 中的方案延续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46958496/

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