120 likes | 198 Views
Explore advanced techniques in Scheme for traversing and processing data using abstractions, unions, and compacting functions. Learn how to apply map, fold, and visitor patterns effectively. Enhance your programming skills with practical examples.
E N D
Abstraction Lab 3 Karl Lieberherr
Abstractions in Scheme for traversing and processing data • lists • map: same function applied to all elements • records • explicitly enumerate relevant elements • Example: BusRoute example (Lab 1) • (define (proc-towns towns) (map proc-town towns)) • (define (proc-town town) (proc-busStops(Town-busStops town)))
Abstractions in Scheme for traversing and processing data unions: explicitly enumerate relevant alternatives in cond clause. ;; capacity checking example (define (weight-item l) (cond [(Simple? l) (Simple-weight l)] [(Container? l) (weight-container l)]))
compacting information: variants of map • (andmap p alox) • determine whether p holds for every item on alox • (ormap p alox) • determine whether p holds for at least one item on alox
Compacting information with fold • (foldr + 0 (map weight-item l)) (Capacity checking example) • Two versions: foldr and foldl • Very flexible because compacting function is a parameter (+ above)
Container capacity example (define-struct Container (contents capacity)) (define-struct Simple (name weight))
A more interesting use of map and fold (define (check ac) (wv-violations ((make-Container-Visitor (lambda (name weight) (make-wv weight 0)) (lambda (wvs capacity) (let* ((totals (foldr (lambda (wv1 wv2) (make-wv (+ (wv-weight wv1) (wv-weight wv2)) (+ (wv-violations wv1) (wv-violations wv2)))) (make-wv 0 0) wvs)) (total-weight (wv-weight totals)) (total-violations (wv-violations totals))) (make-wv total-weight (if (> total-weight capacity) (+ 1 total-violations) total-violations))))) ac)))
Functional Visitor: does traversal (define (make-Container-Visitor simple-visitor container-visitor) (define (visitor c) (cond ((Simple? c) (simple-visitor (Simple-name c) (Simple-weight c))) ((Container? c) (container-visitor (map visitor (Container-contents c)) (Container-capacity c))) (else ???))) visitor)
filter ;; filter : (X -> boolean) (listof X) -> (listof X) (eliminate-expensive u toys) Question: does it make sense to generalize filter to any kind of Scheme structure? • consider a container c • filter-struct : (X -> boolean) (structure containing X) -> (structure containing X)
Exercise: filter • Design a dir structure (HTDP 224 -226) and filter out all files whose size is greater than 100. • Choose a structure that minimizes conditionals.
apply: from help desk procedure: (apply proc arg1 ... args) proc must be a procedure and args must be a list. Calls proc with the elements of the list (append (list arg1 ...) args) as the actual arguments. (apply + (list 3 4)) ===> 7 (define compose (lambda (f g) (lambda args (f (apply g args))))) ((compose sqrt *) 12 75) ===> 30
Exercise: apply and eliminate lambda (define compose (lambda (f g) (lambda args (f (apply g args))))) (define (compose2 f g) (lambda args (f (apply g args)))) (define (compose3 f g) (local (define (myf args) (f (apply g args)))) myf)) ((compose sqrt *) 12 75) ((compose2 sqrt *) 12 75) ((compose3 sqrt *) '(12 75)) How can we write compose3 without requiring the ‘?