在我正在选修的一门计算机科学课程中,关于家庭作业,我们被要求回答几个不同的问题,这些问题都与信息传递有关。我已经解决了除一个之外的所有问题,这要求如下:
编写一个不接受参数并返回消息传递对象的邮件对象工厂
(make-mailman),该对象响应以下消息:
'add-to-route:返回接收任意数量邮箱对象并将其添加到邮递员对象的“路由”的过程'collect-letters:返回一个过程,该过程接收任意数量的信函对象,并收集它们以供将来分发'distribute:将收集到的信件添加到邮递员路线上的邮箱,其地址与信件的目的地匹配,并返回目的地与路线上的任何邮箱不匹配的信件列表(注意:每次传递'distribute后,邮递员对象都不应该有收集到的信件)。为使代码更容易编写而给出的一些注释包括:
'get-latest-message传递到邮箱而返回。. args语法接受任意数量的参数。这就是我自己想出来的:
(define (make-mailman)
(let ((T '()))
(define (route-adder . mobjects)
(assoc mobjects T))
(define (letter-collecter . lobjects)
(assoc lobjects T))
(define (add-to-route mobjects)
(begin (set! T (cons (route-adder . mobjects) T)) 'done))
(define (collect-letters lobjects)
(begin (set! T (cons (sort-strings (letter-collecter . lobjects)) T)) 'done))
(define (dispatch z)
(cond ((eq? z 'add-to-route) add-to-route)
((eq? z 'collect-letters) collect-letters)
((eq? z 'distribute) "unsure of what to do here")
(else "Invalid option")))
dispatch))我在这里所能得到的任何帮助都将受到感谢,因为我已经尝试了很长一段时间来研究这个问题,并且无法从这里知道该做什么。
发布于 2013-05-07 14:46:46
你的代码有各种各样的混淆。)让我们一步一步地前进。
dispatch位几乎没有问题:
(define (make-mailman)
(let ...
...
(define (dispatch msg) ;; use short but suggestive var names
(cond
((eq? msg 'add-to-route) add-to-route)
((eq? msg 'collect-letters) collect-letters)
((eq? msg 'distribute)
;; "unsure of what to do here" <<-- Distribute the letters, what else?
distribute-the-letters)
(else "Invalid option")))
dispatch))对于这样的对象,样例调用将是(define ob (make-mailman)),然后是((ob 'add-to-route) box1 box2 ... boxn)等。因此,必须以这种方式定义add-to-route过程:
(define (make-mailman)
(let ((self (list '(ROUTE) ; each mailman has a route, and a mailbag
'(MAILBAG)))) ; use suggestive name here (T, what T?)
...
(define (add-to-route . mailboxes)
(let ((route (assoc 'ROUTE self)))
(set-cdr! route
(append mailboxes ; there will be no duplicates
(cdr route)))
'DONE))对吗?信中也是如此:
(define (collect-letters . letters)
(let ((mailbag (assoc 'MAILBAG self)))
.....
'DONE))现在我们可以处理缺失的部分了,distribute-the-letters
(define (distribute-the-letters)
;; for each letter in my mailbag
(let* ((mailbag (assoc 'MAILBAG self))
(mailboxes (cdr (assoc 'ROUTE self)))
(letters (cdr mailbag)))
(if (null? letters) ()
(let loop ((letter (car letters))
(letters (cdr letters))
(not-delivered ()))
;; access its address,
(let* ((address (letter 'get-address))
;; (we assume it supports this interface,
;; or maybe that's part of a previous assignment)
;; and find a mailbox on my route such that
(mbx (find-mailbox address mailboxes)))
;; its address matches the letter's
;; and if so,
(if .....
;; put that letter into this mailbox:
((mbx 'put-letter) letter)
;; (we assume it supports this interface,
;; or maybe that's part of a previous assignment)
;; but if not, add letter to the "not-delivered" list
..... )
(if (null? letters)
;; having emptied the mailbag, return the "not-delivered" list
(begin (set-cdr! mailbag nil) not-delivered)
(loop (car letters) (cdr letters) not-delivered)))))))我们假设letter和mailbox对象都支持消息类型'get-address,它们都返回相同的address类型的对象,而mailbox对象支持'put-letter消息。
发布于 2013-05-05 14:49:24
除了消息功能的细节之外,看起来您已经完成了它。然而,也有一些错误:
这个(route-adder . mobjects)应该是(router-adder objects),类似于(letter-collector . lobjects)。
不需要使用begin。(define (func . args) <body> ...)的主体隐式地包含在begin中。
具体而言,您的代码可以编写为:
(define (make-mailman)
(let ((T '()))
;; ...
(lambda (z)
(case z
((add-to-route) add-to-route)
((collect-letters) collect-letters)
((distribute) distribute)
(else (error "Invalid option"))))))但你可能还不知道case或者lambda .
至于解决实际的消息传递功能。您需要维护一组邮箱,每个邮箱都要保存一组信件。一封信大概包括一个地址和一些内容(回执地址的额外信用)。分发行为将检查每个字母上的地址,并将其存入其邮箱。邮递员将需要持有信件(在他的路线收集-信件),直到指示分发。
为此,您可以首先构建更低级别的功能,然后使用较低级别来构建实际的消息传递功能。例如,开始时:
(define (make-letter addr content)
`(LETTER ,addr ,content))
(define letter-addr cadr)
;; ...
(define (make-mailbox addr)
'(MBOX ,addr))
(define mailbox-letters cddr)
(define (mailbox-letters-add mailbox letter)
(set-cdr! (cdr mailbox) (cons letter (mailbox-letters mailbox))))
;;...https://stackoverflow.com/questions/16380479
复制相似问题