这在Scheme语言中起什么作用?

时间:2015-05-06 23:07:32

标签: function functional-programming scheme

我是新手,我对语言不太了解。有人可以向我解释一下这个功能是做什么的吗?

第一个功能:

(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)))
))

我确实理解了开始,但我理解的条件并不理解。有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

我将调用您的第二个函数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   )

请参阅?第一个计算参数列表中的某些,第二个将它们相加。

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

答案 1 :(得分:1)

您可能已经注意到两者几乎完全相同。它们都在树上积累(折叠)。它们都将在空树上评估为0,并且当汽车为car时,它们将对cdrlist?上的相同过程的结果求和。当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)