Scheme null?声明

时间:2017-04-30 18:12:19

标签: lambda null scheme conditional-statements

我对Scheme编程语言很陌生,我只是无法弄清楚这两段代码之间的区别,特别是我指出的那些代码。

;program that returns the Nth element in a list where N is an integer argument

(define getElement
(lambda (N L)
(cond
  ((null? L) '() )
  ((= N 1) (car L))
  (#t(getElement (- N 1) (cdr L)));this line
)
)
)

;takes a list L and a number N and returns the list L but with the first N elements removed
(define remove
(lambda (N L)
(cond
  ((null? L) '() )
  ((= N 0) L)
  (#t(remove (- N 1) (cdr L)));and this line
)
)
)

为什么这些程序的输出如此不同?除了检查列表是否为空以及整数N是否为某个值之外,我无法看到条件语句之后的2行对程序输出有什么影响,请执行此操作。

这是我的第一篇文章,欢迎任何建议

3 个答案:

答案 0 :(得分:2)

这两个函数都是递归的,并使用相同的递归策略。但是,当你到达递归的底部时,它们会做很多不同的事情。

每个函数将n减少一个,并将列表减少一个元素,在新上下文中调用自身。 因此,列表(至少在函数的参数中表示)在两种情况下都会变得越来越短。 remove函数返回整个剩余列表。由于已经从remove函数的参数中的列表副本中删除了许多元素,因此这具有返回缩短列表的效果。 但是,第n个元素函数不会返回列表;它返回(car l),或者返回l中包含的cons单元格中的元素。也就是说,它只返回列表的当前元素。 这就是他们产生不同结果的原因。

答案 1 :(得分:1)

正如你所说,

  

如果整数N是某个值,请执行此操作

,区别在于“做这个”。

第一个,

((= N 1) (car L))

说“要获取列表的第一个元素,请选择列表的car”。

第二个,

((= N 0) L)

说“要从列表中删除任何元素,请返回整个列表”。

递归看起来完全相同,但第一个读取“从列表的N - 1获取元素cdr”,而第二个读取“remove {{ 1}}列表中N - 1的元素“。

(看起来第一个函数已经从Lisp翻译过来,其中cdr是“false-y”。更多的Scheme-y函数将返回nil。)

答案 2 :(得分:0)

您指示的行数相同。 完全没有区别!它减少了索引并将列表更改为cdr

当基本案例命中第一个元素时返回第一个元素,第二个元素返回列表。

(getElement 1 '(1 2 3)) ; ==> 1, Since it does (car L)
(remove 0 '(1 2 3))     ; ==> (1 2 3), since it does L

现在,如果您getElement的工作方式list-ref 0应该是基本情况,则与remove相同。此外,当索引为零之前列表为空时,它应该发出错误信号。这更像是:

#!r6rs
(import (rnrs))
(define (my-list-ref lst pos)
  (cond ((null? lst) (raise 'list-too-short))
        ((zero? pos) (car lst))
        (else (my-list-ref (cdr lst) (- pos 1)))))

(my-list-ref '() 1)
; ==> uncaught exception: list-too-short