如果你递归定义你的数据结构,那么自然会出现递归计数算法:
;; Utils
(define (list-ref-at n)
(lambda (l) (list-ref l n)))
(define (eq-to x)
(lambda (y) (eq? x y)))
;; Data Type
(define (make-bae op arg1 arg2)
`(BAE ,op, arg1, arg2))
(define (bae? thing)
(and (list? thing) (eq? 'BAE (car thing)) (= 4 (length thing))))
(define bae-op (list-ref-at 1))
(define bae-arg1 (list-ref-at 2))
(define bae-arg2 (list-ref-at 3))
;; Walk
(define (bae-walk func bae) ;; 'pre-ish order'
(if (not (bae? bae))
(func bae)
(begin
(func (bae-op bae))
(bae-walk func (bae-arg1 bae))
(bae-walk func (bae-arg2 bae)))))
;; Count
(define (bae-count-if pred bae)
(let ((count 0))
(bae-walk (lambda (x)
(if (pred x)
(set! count (+ 1 count))))
bae)
count))
(define (bae-count-if-plus bae)
(bae-count-if (eq-to '+) bae))
> bae
(BAE + (BAE * (BAE + 4 1) (BAE + 5 2)) (BAE - 6 3))
> (bae-count-if-plus bae)
3
;; Find
(define (bae-find-if pred bae)
(call/cc (lambda (exit)
(bae-walk (lambda (x)
(if (pred x) (exit #t)))
bae)
#f)))