;; A Visitor is a structure made up of two functions ;; One for the base case and ;; one for the inductive case (define-struct Visitor (fBase fInduct)) ;; execute: list-of-any1 Visitor any2 --> any3 ;; Executes ("accepts") the visitor on the list ;; returning the result. ;; param is passed to the visitor unmodified. ;; The base case of the Visitor is called on the empty list: ;; Visitor-fBase: list-of-any1 any2 --> any3 ;; The inductive case is called on the non-empty list. ;; Visitor-fInduct: list-of-any1 any2 --> any3 (define (execute a-list visitor param) (cond [(empty? a-list) ((Visitor-fBase visitor) a-list param)] [(cons? a-list) ((Visitor-fInduct visitor) a-list param)])) #| ;; Visitor template using local (define listVisitor (local [(define (fBase a-list param) ...) (define (fInduct a-list param) (...(first a-list)...(execute (rest a-list) listVisitor ...)))] (make-Visitor fBase fInduct))) |# #| ;; Visitor template, using lambda (define listVisitor (make-Visitor (lambda (a-list param) (...param...)) (lambda (a-list param) (...(first a-list) (execute (rest a-list) listVisitor ...)... param...)))) |# ;; sums a list of numbers ;; param is ignored. (define sumVisitor (local [(define (fBase a-list param) 0) (define (fInduct a-list param) (+ (first a-list) (execute (rest a-list) sumVisitor 0)))] (make-Visitor fBase fInduct))) "sumVisitor test case:" (= 28 (execute (list 4 2 7 3 5 6 1) sumVisitor 0)) ;;reverseVisitor reverses a list (define reverseVisitor (local [(define (fBase a-list param) empty) (define (fInduct a-list param) (execute a-list reverseVisitorHelper empty)) ;; reverseVisitorHelper reverses a list ;; The reversed list is prepended onto the param. (define reverseVisitorHelper (local [(define (fBase a-list param) param) (define (fInduct a-list param) (execute (rest a-list) reverseVisitorHelper (cons (first a-list) param)))] (make-Visitor fBase fInduct)))] (make-Visitor fBase fInduct))) "reverseVisitor test case:" (equal? (list 7 6 5 4 3 2 1) (execute (list 1 2 3 4 5 6 7) reverseVisitor 0)) ;; prodVisitor multiplies all the elements of a list together. ;; param is ignored. (define prodVisitor (make-Visitor (lambda (a-list param) 1) (lambda (a-list param) (* (first a-list) (execute (rest a-list) prodVisitor param))))) "prodList test case:" (= 5040 (execute (list 1 2 3 4 5 6 7) prodVisitor empty))