4

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

另外,我知道你可以使用 set!更新列表,但我一直看到手册说使用 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

谢谢!

4

3 回答 3

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:

#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

于 2012-04-28T03:56:32.343 回答
3

正如问题中所述,这真的,真的不是在Scheme中做事的方式;但是,您可以通过全局定义并选择允许重新定义初始绑定的语言来实现您在 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这是解决问题的功能方式。

于 2012-04-28T04:37:19.570 回答
1
(remove "$$" list1)

删除“$$”返回list1,但不更改 list1。所以解决办法是用调用调用display remover

(display (remover list1))

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

(define (remover list1) (remove "$$" list1))
于 2012-04-28T04:29:13.380 回答