我需要一些关于抽象find
和check-callback
函数的建议。代码工作正常,但似乎有很多不必要的重复。是否有更优雅的方式重写它们?
;; Model
(define-struct contact (name phone))
(define phonebook (list (make-contact 'adam 5551212)
(make-contact 'brian 5552323)
(make-contact 'chris 5558888)))
;; find: (string->symbol, string->number) item (listof items) -> symbol/number/false
(define (find type item pb)
(cond
[(empty? pb) false]
[(equal? (string->symbol item) (contact-name (first pb))) (contact-phone (first pb))]
[(equal? (string->number item) (contact-phone (first pb))) (contact-name (first pb))]
[else (find type item (rest pb))]))
;; Controller
(define (check-callback b)
(cond
[(number? (find string->symbol (text-contents a-text-field) phonebook))
(draw-message a-msg (number->string (find string->symbol (text-contents a-text-field) phonebook)))]
[(symbol? (find string->number (text-contents a-text-field) phonebook))
(draw-message a-msg (symbol->string (find string->number (text-contents a-text-field) phonebook)))]
[else (draw-message a-msg "Not found")]))
;; View
(define a-text-field
(make-text "Enter a name or phone number"))
(define a-msg
(make-message ""))
(define a-button
(make-button "Search" check-callback))
(create-window
(list (list a-text-field)
(list a-button)
(list a-msg)))
答案 0 :(得分:1)
由于未使用type
变量,我从代码中省略了它并进行了一些重构:
;; find
(define (find item pb)
(let* ((first-pb (first pb))
(name (contact-name first-pb))
(phone (contact-phone first-pb)))
(cond
[(empty? pb) #f]
[(equal? (string->symbol item) name) phone]
[(equal? (string->number item) phone) name]
[else (find item (rest pb))])))
;; Controller
(define (check-callback pb)
(let ((res (find (text-contents a-text-field) pb)))
(draw-message a-msg
(cond
[(number? res) (number->string res)]
[(symbol? res) (symbol->string res)]
[else "Not found"]))))
或者您可以立即将姓名和手机转换为字符串:
;; find
(define (find item pb)
(let* ((first-pb (first pb))
(name (contact-name first-pb))
(phone (contact-phone first-pb)))
(cond
[(empty? pb) #f]
[(equal? (string->symbol item) name) (number->string phone)]
[(equal? (string->number item) phone) (symbol->string name)]
[else (find item (rest pb))])))
;; Controller
(define (check-callback pb)
(let ((res (find (text-contents a-text-field) pb)))
(draw-message a-msg
(if (res)
res
"Not found"))))