gpt4 book ai didi

oop - DrRacket : How can I store an "equality detector" in a compound variable?

转载 作者:太空宇宙 更新时间:2023-11-03 19:00:07 24 4
gpt4 key购买 nike

如果您愿意,请将标题更改为更合适的名称。

我正在以面向对象程序的形式制作一些东西,这里定义了一个名为 world 的复合体:

(define-struct world (var1 var2 var3 loo))

其中“var”1 到 3 是Number,代表一些世界变量,如温度、湿度等。loo 是“list of objects”的缩写,对象被定义下面:

(define-struct obj (id act))

其中 idInteger 并且是对象的 ID,而 act 是另一个复合:

(define-struct act (trigger command))

其中trigger后面会解释,command是一个String,代表一个command,会在程序的其他部分解析。

这是我的问题:我希望 trigger 是一个表达式,如果世界上的某些变量以某种方式返回 true,例如,我想使 var1var2 具有相同的值时,发出命令 "start-rain"。一段“虚构的”代码如下所示:

(define (get-commands loo0)
(local [(define (fn-for-loo todo rsf)
(cond [(empty? todo) rsf]
[else (fn-for-obj (first todo)
(rest todo)
rsf)]))

(define (fn-for-obj obj todo rsf)
(if (true? (act-trigger (obj-act obj)))
(fn-for-loo todo (cons (act-command (obj-act obj)) rsf))
(fn-for-loo todo rsf)))]
(fn-for-loo loo0 empty)))

如果难以理解,这里有一个带注释的版本:

(define (get-commands loo0) ;;-------------------------------------------------This function returns (listof String), it uses local for tail-recursion
(local [(define (fn-for-loo todo rsf) ;;------------------------------------rsf is result-so-far accumulator, it is (listof String)
(cond [(empty? todo) rsf] ;;-------------------------------------rsf returned as final output of entire function when all objects are checked
[else (fn-for-obj (first todo) ;;--------------------------if some objects are unchecked, pass objects to fn-for-obj to check the first
(rest todo)
rsf)]))

(define (fn-for-obj obj todo rsf) ;;--------------------------------receiving one object of attention, other unchecked object and result-so-far
(if (true? (act-trigger (obj-act obj))) ;;-----------------------if the trigger returns true...
(fn-for-loo todo (cons (act-command (obj-act obj)) rsf)) ;;--add current object's command to the list of commands and pass on to fn-for-loo
(fn-for-loo todo rsf)))] ;;----------------------------------if trigger returns false, pass on without modification to rsf
(fn-for-loo loo0 empty))) ;;---------------------------------------------this kick-starts the local functions

我的问题是我不知道 trigger 应该是什么,它必须是根据 world 中的变量返回 Boolean 的东西.当然,世界的变量可以通过词法作用域或直接引用访问,但是我如何在程序知道之前在 object 中编写 trigger 的表达式世界变量将可用?

我正在尝试这样的事情:

(define OBJ1 (make-obj 1
(make-act (= var1 var2) "start-rain")))

但编译器说“var1 未定义”

最佳答案

如果你想访问世界的一部分,你需要传递世界:

(define (get-commands w loo0)
(local [(define (fn-for-loo todo rsf)
(cond [(empty? todo) rsf]
[else (fn-for-obj (first todo)
(rest todo)
rsf)]))

(define (fn-for-obj obj todo rsf)
(if ((act-trigger (obj-act obj)) w)
(fn-for-loo todo (cons (act-command (obj-act obj)) rsf))
(fn-for-loo todo rsf)))]
(fn-for-loo loo0 empty)))

(define OBJ1
(make-obj 1
(make-act (lambda (w) (= (world-var1 w) (world-var2 w)))
"start-rain")))

(define OBJ2
(make-obj 2
(make-act (lambda (w) (= (world-var1 w) (world-var3 w)))
"go-home")))

(true? 谓词不是很有用。)

测试:

(define w0 (make-world 1 1 1 (list OBJ1 OBJ2)))

> (get-commands w0 (world-loo w0))
'("go-home" "start-rain")

许多人更愿意使用标准的高阶函数:

(define (get-commands w loo0)
(foldl (lambda (o rs) (if ((act-trigger (obj-act o)) w)
(cons (act-command (obj-act o)) rs)
rs))
'()
loo0))

请注意,您的代码以列表中对象的相反顺序生成命令。

如果你想让它们按相同的顺序排列,你可以这样做:

(define (get-commands w loo0)
(foldr (lambda (o rs) (if ((act-trigger (obj-act o)) w)
(cons (act-command (obj-act o)) rs)
rs))
'()
loo0))

或者这个:

(define (get-commands w loo0)
(let ((triggered (filter (lambda (o) ((act-trigger (obj-act o)) w)) loo0)))
(map (lambda (o) (act-command (obj-act o))) triggered)))

关于oop - DrRacket : How can I store an "equality detector" in a compound variable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41252755/

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