Lambda 将元素添加到方案中的关联列表中
我正在学习这个计划,并在我现有知识的限制下前进。我怀疑宏可能是这项工作的正确工具,但是 我想编写一个过程,其中关联列表的内容根据用户提供的表达式进行操作。如果我们有这个协会名单Lambda 将元素添加到方案中的关联列表中,lambda,macros,scheme,eval,Lambda,Macros,Scheme,Eval,我正在学习这个计划,并在我现有知识的限制下前进。我怀疑宏可能是这项工作的正确工具,但是 我想编写一个过程,其中关联列表的内容根据用户提供的表达式进行操作。如果我们有这个协会名单 (define a '((x (1 2 3)) (y (4 5 6)) (z (7 8 9)))) 然后,我希望有一个过程,根据关联列表的当前元素向关联列表添加新元素 (define (add-element alist proc) ;; this is part that I'm struggling with
(define a '((x (1 2 3)) (y (4 5 6)) (z (7 8 9))))
然后,我希望有一个过程,根据关联列表的当前元素向关联列表添加新元素
(define (add-element alist proc)
;; this is part that I'm struggling with
)
下面是几个用法示例:
(add-element a '(w (* x y z)))
(add-element a '(w (- (+ y z) (/ y 2)))
我想将这些输入转换为以下内容(对于第二个示例):
这个问题有些地方似乎是可以解决的。例如,用户定义过程的结构使得(car-proc)
为新的关联列表元素提供键,(cadr-proc)
提供lambda
主体。我编写了一个过程(此处未显示),用于展平(car proc)
,提取在关联列表的键中找到的符号,并删除重复项。然后,我可以使用该符号列表映射关联列表,并从关联列表中获取相关元素的列表,这样我就可以使用apply map
模式和lambda
功能。但我不知道如何将lambda
函数与符号列表组合在一起。或者如何在lambda
正文中使用(cadr proc)
编辑:添加代码以显示使用eval
失败的尝试
;; https://stackoverflow.com/questions/8382296/scheme-remove-duplicated-numbers-from-list
(define (remove-duplicates ls)
(cond [(null? ls)
'()]
[(member (car ls) (cdr ls))
(remove-duplicates (cdr ls))]
[else
(cons (car ls) (remove-duplicates (cdr ls)))]))
;; https://stackoverflow.com/questions/28753729/how-to-manually-flatten-a-list-in-racket-scheme
(define (flatten obj)
(cond [(null? obj) '()]
[(list? obj)
(append (flatten (car obj))
(flatten (cdr obj)))]
[else (list obj)]))
(define (alist-contains? alist symbol)
(if (member symbol (map car alist)) #t #f))
(define (extract-alist-keys alist expr)
(remove-duplicates
(filter
(lambda (x)
(and (symbol? x) (alist-contains? alist x)))
(flatten expr))))
(define (add-element alist proc)
(define new-key (car proc))
(define body (cadr proc))
(define key-list (extract-alist-keys alist body))
(define values-list (map (lambda (x) (cadr (assoc x alist))) key-list))
(define new-values (eval '(apply map (lambda ,key-list body) ,values-list)))
(cons (list new-key new-values) alist))
(add-element a '(w (- (+ y z) (/ y 2))))
您需要实现
eval
,因为符号+
和作为求值结果的过程没有任何共同之处。如果你想要一个宏,那么你需要松开引号,因为它放错了位置,给人的印象是你可以传递求值表达式,而你不能。我添加了代码,希望能揭示我对如何使用eval
”(apply map(lambda,key list body),values list)的困惑。
看起来不太正确uquote
仅适用于quasikote
,而不适用于quote
。对于感兴趣的读者:这个问题反映了我对如何处理此类问题的一些困惑。最近,我问了一个与同一个一般问题相关的更集中的问题,并得出了一个基于宏的解决方案。
;; https://stackoverflow.com/questions/8382296/scheme-remove-duplicated-numbers-from-list
(define (remove-duplicates ls)
(cond [(null? ls)
'()]
[(member (car ls) (cdr ls))
(remove-duplicates (cdr ls))]
[else
(cons (car ls) (remove-duplicates (cdr ls)))]))
;; https://stackoverflow.com/questions/28753729/how-to-manually-flatten-a-list-in-racket-scheme
(define (flatten obj)
(cond [(null? obj) '()]
[(list? obj)
(append (flatten (car obj))
(flatten (cdr obj)))]
[else (list obj)]))
(define (alist-contains? alist symbol)
(if (member symbol (map car alist)) #t #f))
(define (extract-alist-keys alist expr)
(remove-duplicates
(filter
(lambda (x)
(and (symbol? x) (alist-contains? alist x)))
(flatten expr))))
(define (add-element alist proc)
(define new-key (car proc))
(define body (cadr proc))
(define key-list (extract-alist-keys alist body))
(define values-list (map (lambda (x) (cadr (assoc x alist))) key-list))
(define new-values (eval '(apply map (lambda ,key-list body) ,values-list)))
(cons (list new-key new-values) alist))
(add-element a '(w (- (+ y z) (/ y 2))))