[The Little Schemer] 06 Shadows

Posted by roife on Sat, Jan 4, 2020

表达式计算

  • (numbered? aexp) 表示询问 aexp 是否为 +,*,^ 和数字组成的运算式子,如 (1 + (3 + 2))
(define numbered?
  (lambda (aexp)
    (cond
     ((atom? (car aexp)) (number? (car aexp)))
     ((eq? (car (cdr aexp)) '+) (and (numbered? (car aexp)) (numbered? (cdr (cdr aexp)))))
     ((eq? (car (cdr aexp)) '*) (and (numbered? (car aexp)) (numbered? (cdr (cdr aexp)))))
     ((eq? (car (cdr aexp)) '^) (and (numbered? (car aexp)) (numbered? (cdr (cdr aexp)))))
     (else #f))))
  • (1st-sub-exp) 返回第一个表达式的值
(define 1st-sub-exp
  (lambda (x)
    (car (cdr aexp))))

(define 2nd-sub-exp
  (lambda (x)
    (car (cdr (cdr aexp)))))

(define operator
  (lambda (x)
    (car aexp)))
  • (value aexp) 计算 aexp,其中 aexp 是前缀表达式,如 (+ 3 4)
(define value
  (lambda (nexp)
    (cond
     ((atom? nexp) nexp)
     ((eq? (operator nexp) '+)
      (o+ (value (1st-sub-exp nexp))
          (value (2nd-sub-exp nexp))))
     ((eq? (operator nexp) '*)
      (o* (value (1st-sub-exp nexp))
          (value (2nd-sub-exp nexp))))
     (else (^ (value (1st-sub-exp nexp))
              (value (2nd-sub-exp nexp)))))))

如果想要改为求中缀表达式只需要修改 1st-sub-exp 等几个函数

用括号表示数字

尝试使用括号嵌套来表达数字,如 () 表示 0,(()()) 表示 2,下面尝试编写配套的函数 sero? & zero?edd1 & add1zub1 & sub1o+' & o+

(define sezo? (lambda (n) (null? n)))

(define edd1 (lambda (n) (cons '() n)))

(define zub1 (lambda (n) (cdr n)))

(define o+'
  (lambda (n m)
    (cond
     ((sero? n) m)
     (else (cons '() (o+' (zub1 n) m))))))