gpt4 book ai didi

binding - 如何在 lambda 上刷新、重制、词法绑定(bind)?

转载 作者:太空宇宙 更新时间:2023-11-03 18:46:35 25 4
gpt4 key购买 nike

我正在尝试查看如何重新绑定(bind)词法绑定(bind),或者重新定义关闭 lambda。 next-noun 的预期用法只是不带参数地任意多次调用它。它应该从列表中返回一个随机名词,但直到列表用完才返回一个。

这是我正在使用的玩具示例:

#lang racket

(define nouns `(time
year
people
way
day
man))

(define (next-noun)
(let* ([lst-nouns (shuffle nouns)]
[func-syn
`(λ ()
(let* ([n (car lst-nouns)]
[lst-nouns (if (null? (cdr lst-nouns))
(shuffle nouns)
(cdr lst-nouns))])
(set! next-noun (eval func-syn))
n))])
((eval func-syn))))

尝试运行它时出现此错误:

main.rkt> 
main.rkt> (next-noun)
; lst-nouns: undefined;
; cannot reference an identifier before its definition
; in module: "/home/joel/projects/racket/ad_lib/main.rkt"

这让我很困惑,因为对于 lst-nouns any 应该有一个绑定(bind)时间(eval func-syn)运行。怎么回事?

最佳答案

你根本不需要在这里使用eval。它使解决方案比需要的更复杂(和 insecure )。此外,“循环”逻辑是不正确的,因为您没有更新 lst-nouns 中的位置,而且每次调用过程时它都会重新定义。另请参阅 link由 Sorawee 共享以了解为什么 eval 看不到本地绑定(bind)。

在 Scheme 中,我们尽量避免改变状态,但对于这个过程,我认为这是合理的。诀窍是将需要更新的状态保存在闭包中;这是一种方法:

(define nouns '(time
year
people
way
day
man))

; notice that `next-noun` gets bound to a `lambda`
; and that `lst-nouns` was defined outside of it
; so it's the same for all procedure invocations
(define next-noun
; store list position in a closure outside lambda
(let ((lst-nouns '()))
; define `next-noun` as a no-args procedure
(λ ()
; if list is empty, reset with shuffled original
(when (null? lst-nouns)
(set! lst-nouns (shuffle nouns)))
; obtain current element
(let ((noun (car lst-nouns)))
; advance to next element
(set! lst-nouns (cdr lst-nouns))
; return current element
noun))))

@PetSerAl 在评论中提出了一个更惯用的解决方案。我的猜测是你想从头开始实现这个,用于学习目的 - 但在现实生活中我们会做这样的事情,使用 Racket 的 generators :

(require racket/generator)

(define next-noun
(infinite-generator
(for-each yield (shuffle nouns))))

无论哪种方式,它都按预期工作 - 重复调用 next-noun 将返回 nouns 中的所有元素,直到耗尽,此时列表将重新洗牌并迭代将重启:

(next-noun)
=> 'day
(next-noun)
=> 'time
...

关于binding - 如何在 lambda 上刷新、重制、词法绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54384930/

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