如何更新Scheme(Racket)中的列表

时间:2012-04-28 03:46:36

标签: list scheme racket

如何将列表发送到单独的函数/过程,从列表中删除项目,更新新列表(删除项目),并从第一个函数/过程中显示它。

另外,我知道你可以使用套装!更新列表,但我一直看到说使用set的手册!不是“计划方式”。

但是,我不明白除了这种方式之外如何创建这个程序(这不起作用):

#lang racket

(define list1 '("read" "id" "$$"))

(define (displayer list1)
  (remover list1)
  (newline)
  (display list1)) ;also doesn't display updated list here

(define (remover list1)
  (remove "$$" list1)
  (display list1))  ;doesn't display updated list here

谢谢!

3 个答案:

答案 0 :(得分:3)

如果我写下你的代码:

(displayer list1)

它会显示:

(read id $$)

但如果我把它改为:

#lang racket

(define list1 '("read" "id" "$$"))

(define (displayer list1)
   (display (remover list1))) 

(define (remover list1)
  (remove "$$" list1)) 

这样当你运行

(displayer list1)

它会返回

(read id)

请记住,在函数式语言中,一切都是表达式并且处理“变量”是不可变的首选方式(无状态工作使得更容易验证,优化和并行化程序,并且更容易编写自动化工具来执行这些任务,请在此处阅读更多内容:http://en.wikipedia.org/wiki/Functional_programming#Comparison_to_imperative_programming) ,所以如果你想从列表中删除一个元素然后显示你必须编写一个返回一个包含较少元素的新列表的函数

另一方面,Racket不是像Haskell那样的纯函数式语言,正如你所提到的,如果你真的想重新定义变量“list1”引用的值,你可以像这样强制使用Racket:< / p>

#lang racket
(define list1 '("read" "id" "$$"))

(define (displayer list1)
  (set! list1 (remover list1))
  (newline)
  (display list1)) 

(define (remover list1)
  (remove "$$" list1))  

设置!重定向list1以指向从现在开始的新值

您可以在此处详细了解:http://htdp.org/2003-09-26/Book/curriculum-Z-H-44.html

答案 1 :(得分:3)

正如问题中所述,这确实是真的不是在Scheme中做事的方式;尽管如此,你可以通过set!实现你在Racket中所要求的 - 一个全局定义并选择一种允许重新定义初始绑定的语言 - 你必须弄乱语言设置的事实应该是一个非常清楚的标志,你做错了。

无论如何,这是如何:

(define list1 '("read" "id" "$$"))

(define (displayer)
  (remover)
  (newline)
  (display list1))

(define (remover)
  (set! list1 (remove "$$" list1))
  (display list1))

(displayer)
> (read id)
> (read id)

更惯用的方法是避免定义全局变量以在过程中修改它们;而是每次你需要修改一个列表时创建一个新列表(remove创建一个新列表)并传递它,如下所示:

(define (displayer lst)
  (let ((removed (remover lst)))
    (newline)
    (display removed)))

(define (remover lst)
  (let ((removed (remove "$$" lst)))
    (display removed)
    removed))

(define list1 '("read" "id" "$$"))
(displayer list1)
> (read id)
> (read id)

请注意,第二个解决方案修改list1,这是解决问题的功能方法。

答案 2 :(得分:1)

(remove "$$" list1)

使用&#34; $$&#34;返回list1已删除,但不会更改 list1。因此解决方案是使用remover调用调用显示:

(display (remover list1))

并重新实现remover以删除&#34; $$&#34;,但没有其他副作用(输出是副作用):

(define (remover list1) (remove "$$" list1))