在 Lisp 中评估函数

Evaluating Function in Lisp

我是 Lisp 的新手,需要帮助来理解这个函数和 (map length '((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6))))

的评估

值为(3 5 6)

(define (map f list)    
  ; applies function f to each element of list
  (if (null? list) 
      ()
      (cons (f (car list)) 
            (map f (cdr list)))))

(define map-test-1
  (map square '(1 2 3 4 5)))
(define map-test-2
  (map length '((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6))))

一般来说,映射的思路是对于任意列表(define lst (list a b c d ... ))和函数f(map f lst)的值与(list (f a) (f b) (f c) (f d) ...)的值相同.


让我们将评估模拟为一系列 减少 步骤:

    (map    square   '(1 2 3 4 5)   )   
;;  (map    f        list           )
=   (let ( (f        square       )       ; definition 
           (list     '(1 2 3 4 5) ) )     ; of `map`
        (if (null? list)             
          ()
          (cons (f     (car list)) 
                (map f (cdr list)))))     ; list is not `null?`, so

=   (let ( (f        square       )
           (list     '(1 2 3 4 5) ) ) 
        (cons (f     (car list))         ; car of list is 1
              (map f (cdr list))))       ; cdr is '(2 3 4 5)

=  (cons (square 1) 
     (let ( (f        square     )       ; simulate the recursive call
            (list     '(2 3 4 5) ) )     ; by updating the arguments
       (map f list)))

=  (cons (square 1) 
     (let ( (f        square     )
            (list     '(2 3 4 5) ) )
        (if (null? list) 
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))

=  (cons (square 1) 
     (let ( (f        square     )
            (list     '(2 3 4 5) ) )
        (cons (f     (car list)) 
              (map f (cdr list)))))

=  (cons (square 1) 
     (cons (square 2) 
       (let ( (f        square     )
              (list     '(3 4 5) ) )
          (map f list))))

...

至于你的第二个例子,'((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6))(list '(a b c) '(1 2 3 4 5) '(v1 v2 v3 v4 v5 v6))是一样的,即它是一个包含三个元素的列表;所以减少变成

(let ((mylist (list '(a b c) '(1 2 3 4 5) '(v1 v2 v3 v4 v5 v6))))
    (let ( (f        length       )       ; definition 
           (list     mylist       ) )     ; of `map`
        (if (null? list)             
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))    ; list is not `null?`, so

=   (let ( (f        length       )
           (list     mylist       ) ) 
        (cons (f     (car list))         ; car of list is '(a b c)
              (map f (cdr list))))       ; cdr is '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6))

=  (cons (length '(a b c)) 
     (let ( (f        length       )     ; simulate the recursive call
            (list     (cdr mylist) ) )   ; by updating the arguments
       (map f list)))

=  (cons (length '(a b c)) 
     (let ( (f        length    )
            (list     '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6)) ) )
        (if (null? list) 
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))

=  (cons (length '(a b c))
     (let ( (f        length    )
            (list     '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6)) ) )
        (cons (f     (car list)) 
              (map f (cdr list)))))

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (let ( (f        length     )
              (list     '((v1 v2 v3 v4 v5 v6)) ) )
          (map f list))))

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (cons (length '(v1 v2 v3 v4 v5 v6)) 
         (let ( (f        length)
                (list     '() ) )
           (if (null? list)             
             ()
             (cons (f     (car list)) 
                   (map f (cdr list))))))))  ; list is now `null?`, so

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (cons (length '(v1 v2 v3 v4 v5 v6)) 
         '())))

QED.