Scheme 语言中的 this 函数是做什么的?

What this functions in Scheme language do?

我是新手,语言不是很懂。谁能给我解释一下这个函数的作用吗?

第一个函数:

(define (x l)
    (cond
        ((null? l) 0)
        ((list? (car l))
                 (+ (x (car l)) (x (cdr l))))
        (else    (+ 1 (x (cdr l))))
))

第二个函数:

(define (x l)
    (cond
        ((null? l) 0)
        ((list? (car l))
                 (+ (x (car l)) (x (cdr l))))
        (else    (+ (car l) (x (cdr l)))
))

开头我看懂了,后面的条件我没看懂。有帮助吗?

我会调用你的第二个函数y

用伪代码编写,

x []      ->  0
x [a . b] -> x a + x b    , if list a
x [a . b] -> 1   + x b    , else, i.e. if not (list a)

y []      ->  0
y [a . b] -> y a + y b    , if list a
y [a . b] ->   a + y b    , else, i.e. if not (list a)

例如,

x [2,3] = x [2 . [3]]
        = 1    + x [3]
        = 1    + x [3 . []]
        = 1    + (1   + x [])
        = 1    + (1   + 0   )

y [2,3] = y [2 . [3]]
        =    2 + y [3]
        =    2 + y [3 . []]
        =    2 + (  3 + y [])
        =    2 + (  3 + 0   )

看到了吗?第一个在参数列表中计算 something,第二个将它们相加。

当然这两个函数都可以用一些非列表来调用,但是这两个函数都只会导致在第二个子句 (list? (car l)) 中尝试获取 (car l) 的错误。

您可能已经注意到两者几乎相同。它们都在树上堆积(折叠)。当汽车是 list? 时,它们都将在空树上评估为 0,并且它们将在 carcdr 上对相同过程的结果求和。当 car 不是列表时,两者不同,第一个是为每个元素加 1,另一个是在加法中使用元素本身。可以像这样写得更紧凑一点:

 (define (sum l)
  (cond
    ((null? l) 0)                            ; null-value
    ((not (pair? l)) l)                      ; term
    (else (+ (sum (car l)) (sum (cdr l)))))) ; combine

这是一个概括:

(define (accumulate-tree tree term combiner null-value)
  (let rec ((tree tree))
    (cond ((null? tree) null-value)
          ((not (pair? tree)) (term tree))
          (else (combiner (rec (car tree)) 
                          (rec (cdr tree)))))))

您可以根据 accumulate-tree:

来制定您的两个程序
(define (count tree)
  (accumulate-tree tree (lambda (x) 1) + 0))

(define (sum tree)
  (accumulate-tree tree (lambda (x) x) + 0))

当然,accumulate-tree 你可以赚到比这更多的钱。它不必变成原子值。

(define (double tree)
  (accumulate-tree tree (lambda (x) (* 2 x)) cons '()))

(double '(1 2 ((3 4) 2 3) 4 5)) ; ==> (2 4 ((6 8) 4 6) 8 10)