乐正

Actions speak louder than words.

Sicp-ex4-5

问题

Scheme还允许另一种形式的cond子句,(<test> => <recipient)。如果test求出的值是真,那么就对recipient求值。这样求出的值必需是一个单个参数的过程,将这一过程应用于test的值,并将其返回值作为这个cond表达式的值。例如:

1
2
(cond ((assoc 'b '((a 1) (b 2))) => cadr)
      (else false))

返回值2。请修改对cond的处理,使之能支持这一语法扩充。

解答

练习4.5 (ex4-5.scm) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(define (cond-recipient-clause? clause)
  (eq? '=> (cadr clause)))

(define (expand-clauses clauses)
  (if (null? clauses)
      #f
      (let ((first (car clauses))
            (rest (cdr clauses)))
        (cond ((cond-else-clause? first)
               (if (null? rest)
                   (sequence->exp (cond-actions first))
                   (error "ELSE clause isn't last -- COND->IF" clauses)))
              ((cond-recipient-clause? first)
               (let ((predicate (car clause))
                     (body (caddr clause))
                     (predicate-value (eval predicate)))
                 (make-if predicate-value
                          (apply body predicate-value)
                          (expand-clauses))))
              (else (make-if (cond-predicate first)
                             (sequence->exp (cond-actions first))
                             (expand-clauses rest)))))))

draft

« sicp-ex4-4 sicp-ex4-6 »

Comments