繁体   English   中英

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

[英]How to update a list in 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

谢谢!

如果我写你的代码:

(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:

#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-ZH-44.html

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

无论如何,这是如何:

(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 ,这是解决问题的功能性的方式。

(remove "$$" list1)

返回list1并删除“$$”,但不更改 list1 因此解决方案是使用remover调用调用display:

(display (remover list1))

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM