Список, переданный процедуре, преобразуется в список списка внутри процедуры - PullRequest
0 голосов
/ 05 ноября 2018

Я отлаживаю этот код на DrRacket:

#lang racket

(define last-element-on-list
   (lambda l
      (cond ((null? l) '())
            ((null? (cdr l)) (car l))
            (else (last-element-on-list (cdr l)))
      )
   )
)

(define lst '(
  (n 25 f +)
  (s 25 m +)
  (ll 20 no -)))

(list-ref lst 0)

(last-element-on-list (list-ref lst 0))

Код (list-ref lst 0) возвращает '(n 25 f +), но когда я вхожу в процедуру last-element-on-list, параметр l имеет значение ((n 25 f +)).

Почему l является списком в процедуре last-element-on-list?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Существует разница между формой (lambda (x) ...) и формой (lambda x ...).

Обратите внимание на разницу между этими двумя примерами:

;; Example 1.
(define f
  (lambda (x)
    (if (list? x)
      (display "x is a list!")
      (display "x is not a list"))))

(f 1)  ; Displays "x is not a list".

;; Example 2.
(define g
  (lambda x
    (if (list? x)
      (display "x is a list!")
      (display "x is not a list"))))

(g 1)  ; Displays "x is a list!".

Форма (lambda x ...) позволяет лямбде принимать любое количество аргументов, причем все аргументы помещаются в список, связанный с x в теле лямбды. то есть x - это список аргументов.

Вот почему, когда вы даете g список (например, (g '(1 2 3))), x будет '((1 2 3)) (список списков).

Чтобы исправить ваш код:

(define last-element-on-list
   (lambda (l)  ; <- ATTENTION.
      (cond ((null? l) '())  ; FIXME: raise error instead.
            ((null? (cdr l)) (car l))
            (else (last-element-on-list (cdr l))))))

Подробнее о lambda вы можете прочитать в The Racket Guide . В частности, смотрите раздел 4.4.1 (Объявление аргумента отдыха).

0 голосов
/ 05 ноября 2018

Я думаю, что будет лучше поднять error при вызове вашей процедуры в пустом списке -

(define last-element-of-list
  (lambda (l)
    (cond ((null? l)
           (error 'last-element-of-list "cannot get last element of empty list"))
          ((null? (cdr l))
           (car l))
          (else
           (last-element-of-list (cdr l))))))


(last-element-of-list '(1))         ;; 1
(last-element-of-list '(1 2))       ;; 2
(last-element-of-list '(1 2 3))     ;; 3
(last-element-of-list '(1 2 3 4))   ;; 4

(last-element-of-list '())          ;; error: cannot get last element of empty list
...