在 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.
我是 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.