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))))