如何更改方案中列表的值

时间:2014-04-30 10:49:40

标签: list racket

我想更改列表编号的值,但它总是显示 设置!:不是(car (cdr (car a)))中的标识符 我不知道该怎么办,谁能帮助我?谢谢先进!

(define a (list (list burnie 236.67) (list launceston 163.66)))
(define-syntax-rule (myset-car! lst val)
  (if (not (list? lst))
      lst
      (set! lst (cons val (cdr lst)))))

(define update_gn
  (lambda (a)
    (cond
      ((null? a) #t)
      (else
      (myset-car! (car (cdr (car a))) (+ (car (cdr (car a))) (car new_gn)))
      (update_gn (cdr a) )))))

2 个答案:

答案 0 :(得分:2)

你不能改变#!racket(语言)中的对,因为它们在偏离Scheme之后使它们成为不可变的。如果您在Racket(应用程序)中使用Scheme语言,您将能够执行此操作:

#!r6rs
(import (rnrs) (rnrs mutable-pairs))

(define test-list (list (list 'burnie 236.67) (list 'launceston 163.66)))
(define new-gn (list 10)) ; I'm not sure what this actually is, but tyhe procedures expect it to be a pair with a numeric car.

(define (update-gn lst)
  (cond
    ((null? lst) #t)
    (else
     (set-car! (cdar lst) (+ (cadar lst) (car new-gn)))
     (update-gn (cdr lst)))))

(update-gn test-list)
test-list ; ==> ((burnie 246.67) (launceston 173.66))

现在,你确实在#!Racket(该语言)中有可变对,但你需要使用mconsmcarmcdr,它们是mpair?而不是pair?。你需要让你拥有cadar这样的(define mcadar (compose mcar mcdr mcar)),而你使用的大多数高阶函数都不支持它们,所以你必须自己制作..这使得它非常痛苦,它就像设计一样。我通常将语言改为R6RS(标准方案),第二个我发现我需要可变对。

答案 1 :(得分:0)

如果您想以这种方式进行更新,您应该使用向量,而不是列表。

使用列表,您应该使用更具功能性的方法,使用高阶函数迭代列表,并返回新列表。例如,要为每个子列表的每个第二个元素添加10:

> (define a (list (list 'burnie 236.67) (list 'launceston 163.66)))
> a
'((burnie 236.67) (launceston 163.66))

> (map (lambda (lst) (list (car lst) (+ (cadr lst) 10))) a)
'((burnie 246.67) (launceston 173.66))
> a ; has not been modified
'((burnie 236.67) (launceston 163.66))

> (set! a (map (lambda (lst) (list (car lst) (+ (cadr lst) 10))) a))
> a ; has been modified
'((burnie 246.67) (launceston 173.66))