recursion - Combined weight of items in list -
i'm working in dr. racket, , it's first time using functional language quite confused.
i need add together weights of each different "animal" in list. different animals have "weight" attribute, racket won't allow me access "weight" item of given list element because claims it's "not defined"
what have far:
(define (zoo-weight animals) (cond [(empty? animals) 0] [else (+ (first weight)(zoo-weight (rest animals)))])) ;this error weight, saying undefined.
if allow me know how reference weight regardless of list item (snake-weight, cow-weight, etc) whole functional thing sort of confusing.
thanks!
you got it! seek this:
(define (zoo-weight animals) (cond [(empty? animals) 0] [else (+ (weight (first animals)) (zoo-weight (rest animals)))]))
the problem can't (first weight)
. weight
? it's function applies animals, or variable. so, wrote: "take first element of weight
". doesn't create sense, want take first animal list, , then find out animal's weight, before advancing next animal in list.
as shown above utilize next look in procedure, should work assuming function gives animal's weight called weight
(if not, utilize appropriate function - animal-wight
, weight-animal
, don't know how called it):
(weight (first animals))
update
now mention each animal has different weight function, have couple of comments. symptom of bad design, same function should work on kinds of animals, avoid long conditionals everywhere (and it'll hassle if add together new kind of animal!). don't know how animals implemented, can't create farther suggestions. if it's not possible prepare current representation, @ to the lowest degree encapsulate conditional in single place, this:
(define (weight animal) ; find right weight function ((cond ((snake? animal) snake-weight) ((dillo? animal) dillo-weight) ((ant? animal) ant-weight) (else (error "unknown animal:" animal))) ; apply function animal animal))
now implementation of zoo-weight
work without modification, , there's no need duplicate conditional wherever weight needed. , if writing more 1 function problem (and can't imagine why teacher set restriction, functional programming encourages building lots of reusable functions!), can in-line code:
(define (zoo-weight animals) (cond [(empty? animals) 0] [else (+ (let ([animal (first animals)]) ((cond ((snake? animal) snake-weight) ((dillo? animal) dillo-weight) ((ant? animal) ant-weight) (else (error "unknown animal:" animal))) animal)) (zoo-weight (rest animals)))]))
also, borrowing @jack's solution, can utilize lambda
(an anonymous function) higher-order map
procedure. still counts single function:
(define (zoo-weight animals) (apply + (map (lambda (animal) ((cond ((snake? animal) snake-weight) ((dillo? animal) dillo-weight) ((ant? animal) ant-weight) (else (error "unknown animal:" animal))) animal)) animals)))
recursion functional-programming racket
No comments:
Post a Comment