获取 Scheme 中列表的最后一个元素

Get the last element of a list in Scheme

我正在关注使用 Scheme 的计算机科学简介。我遇到了以下问题,我想出了一个解决方案,但似乎我迷失了语法。

定义一个 last-pair 过程,returns 只包含 a 的最后一个元素的列表 给定(非空)列表: (最后一对(清单 23 72 149 34))

这是我的解决方案:

   (define (last-pair array) 
     ((define (get-last (length array) array)) 
       (if (= (length array) 1) (car array) 
        (get-last (- 1 (length array)) (cdr array))))))

这是错误:错误:无效的 lambda: (lambda ((length array) array))

错误在:

(define (get-last (length array) array)

定义函数时,必须列出函数名及其参数:

(define (function-name arg1 arg2 ... argN) ...

(length array) 不能作为参数:它是对函数的调用。

反正不用定义get-last。像这样就够了:

(define (last-pair array) 
  (if (= (length array) 1) 
      array
      (last-pair (cdr array))))

在你的程序中你调用了一个定义..

+   ; ==> <procedure: +> (how it's printed varies but it  is the value that can be called)
(+) ; ==> 0 
^- this calls the result for evaluation `+` which is `<procedure: +>`

((define something ...)) ; == (undefined-value) == Error!
^- this calls the result of `(define something ...)`. 

define 将 return 一些依赖于实现的值,在报告中它只是说它是未定义的。您不能假设它与 something 绑定到的值相同(这将是一个不错的未定义值)

此外,您本地 define 的格式未使用标准扩展,这可能适用于某些 Scheme 实现,它在 SRFI-16 中定义,但它不是可移植的功能。

(define (get-last (length array) array)
  ...)

因此,在不允许此扩展的语言中,您会收到错误,而支持扩展的语言可能不会。

最后一对和它之前的一对之间的差异是 cdr 的值。 (cdr '(1 . 2)) ; ==> 2(cdr '(0 1 . 2)) ; ==> (1 . 2)。因此,您可以迭代列表,直到您为 cdr:

找到一个非 pair?
(define (last-pair lst)
  (if (pair? (cdr lst))
      (last-pair (cdr lst))
      lst))

(last-pair '(1 2 3 4 . 5)) ; ==> (4 . 5)

请注意,如果您不给它一对开始,这将失败,就像 carcdr.