修改相交可变对象

时间:2016-11-27 02:06:15

标签: scheme racket

我尝试用相交来制作一个可变函数,但是我认为我严重搞乱了我实现与函数交叉的方式,并且我不确定修复函数的最佳方法。

(define (intersect-mutable)
  (let ((lst '()))
    (let ((lst2 '()))
      (define (insert x)
      (set! lst (cons x lst)))
      (define (intersect)
        (define (helper lst lst2)
          (define contains member)
          (cond ((null? set) '())
                ((contains (car lst) lst2)
                 (cons (car lst) (intersect (cdr lst) lst)))
                (else
                 (intersect (cdr lst) lst2))))
        (helper lst lst2))
      (lambda (function)
        (cond ((eq? function 'intersect) intersect)
              ((eq? function 'insert) insert)
              (else
               'undefined))))))

递归函数的测试用例是:

>(intersection '(2 4 7 10) '(2 9 0 10))
(2 10)
>(intersection '(1 4 10) '(83 1 48 2 4))
(1 4)

插入测试用例:

(define mut (intersect-mutable))
((mut 'insert) 'intersect)
((mut 'insert) 'mutable)

为了澄清,我试图将两个单独的列表交叉到一个列表中。我添加了一个插入函数。

2 个答案:

答案 0 :(得分:0)

使用list->mlist将不可变缺点列表转换为可变缺点列表(mcons单元格)。

在此处查看更多内容:docs

答案 1 :(得分:0)

如果突变只是为了保管这两个清单:

filter

然而,注意到交叉并没有真正改变任何东西。我想也许这一点的重点是OO所以我想我们可以在这样的列表上进行操作:

(define (intersect-mutable (lst1 '()) (lst2 '()))
  (define (method-insert lst1? value)
    (if lst1?
        (set! lst1 (cons value lst1))
        (set! lst2 (cons value lst2)))
    message-handler)

  (define (method-intersect)
    ;; intersect is a working intersect without mutation
    (intersect lst1 lst2)) 

  (define (message-handler msg)
    (case msg
      ((insert) method-insert)
      ((insert1) (lambda (v) (method-insert #t v)))
      ((insert2) (lambda (v) (method-insert #f v)))
      ((lst1) lst1)
      ((lst2) lst2)
      ((intersect) method-intersect)
      (else (error "No such method" msg))))

  message-handler)

(define obj (intersect-mutable '(10) '(30)))
((obj 'insert) #t 5)
((obj 'insert2) 10)
(obj 'lst1) ; ==> (5 10)
(obj 'lst2) ; ==> (10 30)
((obj 'intersect)) ; ==> (10)

想象一下你制作了很多像这样的对象,然后你可以制作(微小的)CLOS类型的通用方法:

(define (list-object (lst '()))
  (define (method-insert . values)
    (set! lst (foldl cons lst values))
    message-handler)

  (define (method-intersect lst2)
    ;; intersect is a working intersect without mutation
    (set! lst (intersect lst lst2))
    message-handler)

  (define (method-member? value)
    (member value lst))

  (define (message-handler msg)
    (case msg
      ((insert) method-insert)
      ((intersect) method-intersect)
      ((member?) method-member?)
      ((lst) lst)             
      (else (error "No such method" msg))))

  message-handler)

(define obj (((list-object '(5)) 'insert) 10 20 30))
(obj 'lst) ; ==> (30 20 10 5)
((obj 'intersect) '(10 30 60))
(obj 'lst) ; ==> (20 30)
相关问题