首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >修改Intersect可变对象

修改Intersect可变对象
EN

Stack Overflow用户
提问于 2016-11-27 10:06:15
回答 2查看 75关注 0票数 1

我试着用intersect创建一个可变函数,但我认为我在函数中实现intersect的方式严重搞砸了,我不确定修复该函数的最好方法。

代码语言:javascript
复制
(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))))))

递归函数的测试用例如下:

代码语言:javascript
复制
>(intersection '(2 4 7 10) '(2 9 0 10))
(2 10)
>(intersection '(1 4 10) '(83 1 48 2 4))
(1 4)

用于插入的测试用例:

代码语言:javascript
复制
(define mut (intersect-mutable))
((mut 'insert) 'intersect)
((mut 'insert) 'mutable)

为了清楚起见,我尝试将两个单独的列表相交为一个列表。我添加了一个插入函数。

EN

回答 2

Stack Overflow用户

发布于 2016-11-27 17:48:56

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

点击此处查看更多信息:docs

票数 0
EN

Stack Overflow用户

发布于 2016-11-27 22:14:21

如果变异只是为了看管这两个列表:

代码语言:javascript
复制
(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)

但是,请注意,intersect并没有真正改变任何东西。我认为这可能是面向对象的,所以我想我们可以像这样对一个列表进行操作:

代码语言:javascript
复制
(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)

想象你制作了许多这样的对象,然后你可以制作(微小的)CLOS类型的泛型方法:

代码语言:javascript
复制
;; generic. Works on any object that has
;; member? method and lists
(define (member? value  obj)
  (if (procedure? obj)
      ((obj 'member?) value)
      (member value obj)))


;; Another object type that has member?
;; only that it means the values binary bits
;; are set on the object
(define (number-object value)
  (define (method-member? value2)
    (= value2 (bitwise-and value value2)))

  (define (message-handler msg)
    (case msg
      ((member?) method-member?)))

  message-handler)

;; test objects
(define num1 (number-object 24))
(define lst1 (list-object '(1 8)))

;; some test
(member? 2 num1); ==> #f
(member? 8 num1); ==> #t
(member? 8 lst1); ==> (8) (true)
(member? 9 lst1); ==> #f
(member? 9 '(1 3 5 9 10)) ; ==> (9 10)

;; map is the ultimate test
(map (lambda (o) (member? 8 o)) (list num1 lst1))
; ==> (#t (8))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40825107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档