【问题标题】:How To Mutate Variables Scheme如何改变变量方案
【发布时间】:2018-08-19 04:24:16
【问题描述】:

我正在尝试使用可变对象对列表求和以进行分配。let 在这里用于允许我改变总和 xcounter。我不太精通方案,因此对列表lst 中的每个数字使用if 语句:

(define lst (list 1 2 3 4 5))

(let mut ((counter 0))
 (let ((x (car lst)))

  (if (= counter 4)
      x)
  (if (= 0 counter)
    (+ x (cadr lst)))
  (if (= 1 counter)
      (display (caddr lst)) ;test
      (+ x (caddr lst)))
  (if (= 2 counter)
      (+ x (caddr lst)))  

  (set-car! lst (cdr lst))   
  (mut (+ counter 1))
  )
)

但是当我运行代码时,我得到一个错误

+: contract violation
      expected: number?
      given: (mcons 2 (mcons 3 (mcons 4 (mcons 5 '()))))
      argument position: 1st
      other arguments...:

但是,当我检查 (caddr lst) 时,它会按预期返回 3我的问题是为什么在运行时,caddr 在应用于+ 时会产生(mcons 2 (mcons 3 (mcons 4 (mcons 5 '())))),但在不应用时会返回3

我正在使用 R5RS 编辑:为了简洁,我省略了一些 if 语句

【问题讨论】:

  • 打开你的解释器。写(define ls '(1 2 3 4))。检查(car ls)(cdr ls)。写(set-car! ls (cdr ls))。再次检查 (car ls)(cdr ls)
  • 您已经跳过了 Scheme 的基础知识,并试图用不同的语言编写程序。从第 1 章重新开始。((if (= counter 4) x)if x == 4: return x不同。)
  • @molbdnilo 我的印象是car 返回的是一个数字而不是一个引用,不是这样吗?
  • Scheme 中没有“引用”。 SICP 可在线免费获取。

标签: scheme lisp racket r5rs mutability


【解决方案1】:

好的,所以我发现它使用了一个完全不同的实现 @molbdnilo 是正确的,我的理解是有缺陷的。 如果其他人正在努力解决这个问题,这是我的实现

(define (goMut)
  (define mVar 0)
  (define acc 0)

(define (accDo num)
    (set! acc (+ num acc)))

  (for-each (lambda (x) (set! mVar x) (accDo x))
            (list 1 2 3 4 5))
  acc
)

使用集合!我们可以将列表中的值应用于外部变量,并在使用函数accDo 遍历整个循环时对其进行变异。函数模板取自 SICP pg 107

【讨论】:

  • 原始代码中的ifs 只需嵌套like so。当然,像这样的嵌套ifs 链最好用cond 编码。在这里,您使用的是现成的 for-each ,但最初您自己进行了迭代。 (最好这样学习?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-30
相关资源
最近更新 更多