Reputation: 159
I am trying to solve following exercise:
I have to implement a function make-empty-as which should return a dispatcher function dispatch which implements some methods for a list of the following structure: ((1 a) (2 b) (3 a) (4 c))
The dispatch function should have 2 parameters. (Only cons and find use both).
Methods should be:
make-empty-as should start with an dispatch function for an empty list.
An example call sequence could be:
(define a1 (make-empty-as))
(define a2 (a1 'cons '(b 2)))
(define a3 (a2 'cons '(d 4)))
(define a4 (a3 'cons '(c 5)))
(define a5 (a4 'cons '(a 6)))
(define a6 (a5 'cons '(c 4)))
(define a7 (a6 'cons '(b 7)))
(define a8 (a7 'cons '(a 1)))
(a8 'find 'b)
=>(7 2)
(a8 'find 'a)
=>(1 6)
(a7 'find 'a)
=>(6)
((a8 'cdr 'dummy) 'find 'a)
=>(6)
As you can see, cons should add an element. And after adding some elements, the elements should be finable with find.
I tried to start with the implementation for cons, but unfortunately I am stuck. I add the passed argument to (), but I dont know how I can save this list for the next call.
My current implementation:
(define (make-empty-as)
(define (dispatch arg1 arg2)
(cond ((eq? arg1 'null?))
((eq? arg1 'car) '())
((eq? arg1 'cdr) '())
((eq? arg1 'cons) (cons arg2 ()) dispatch)
((eq? arg1 'find))
)
)
dispatch
)
If you want to try out the code, you can do that here: https://repl.it/BYpC
Can you help me please?
Regards
Upvotes: 1
Views: 446
Reputation: 18917
Your specs are a little unusual but this passes all your tests:
(define (make-as lst)
(lambda args ; all arguments will be put in a list
(let ((arg1 (car args))) ; first argument
(cond
((eq? arg1 'null?) (null? lst))
((eq? arg1 'cons) (make-as (cons (cadr args) lst))) ; create a new as with element prepended
((eq? arg1 'car) (car lst))
((eq? arg1 'cdr) (make-as (cdr lst))) ; create a new as with fir
((eq? arg1 'find) (map cadr (filter (lambda (e) (eq? (car e) (cadr args))) lst)))))))
(define (make-empty-as)
(make-as '()))
Note that I split the problem in 2 procedures; I could have done it with one and an optional argument but then the naming would have been strange.
Also, no need to give the dispatcher a name (but you could, of course... try this out yourself).
The last test can be simplified to ((a8 'cdr) 'find 'a)
, no need for a dummy argument.
If you are familiar with case
you can trim the first procedure down to
(define (make-as lst)
(lambda args ; all arguments will be put in a list
(case (car args)
((null?) (null? lst))
((cons) (make-as (cons (cadr args) lst))) ; create a new as with element prepended
((car) (car lst))
((cdr) (make-as (cdr lst))) ; create a new as with fir
((find) (map cadr (filter (lambda (e) (eq? (car e) (cadr args))) lst))))))
Does this do what you want?
Upvotes: 2