首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建修改后的“`equal?”函数用于RackUnit

创建修改后的“`equal?”函数用于RackUnit
EN

Stack Overflow用户
提问于 2016-05-12 17:29:59
回答 1查看 35关注 0票数 3

我正在使用check-equal?与包含非eq?语法对象的对象一起编写一系列测试。为了这些测试的目的,我可以说,如果两个语法对象给syntax->datum时是相等的,那么它们是相等的。(是的,我知道有很多绑定信息,但就目前而言,确保它们的数据相等已经足够了。我稍后将测试绑定信息是否良好。)

但是,如果这两个对象不是语法对象,我希望它们在彼此为equal?时是相等的。

但是,如果这些对象在某个递归点上包含语法对象,我想在它们的数据上测试它们的相等性,所以我不能这样做:

代码语言:javascript
复制
(define (my-equal? a b)
  (if (and (syntax? a) (syntax? b)
      (equal? (syntax->datum a) (syntax->datum b))
      (equal? a b)))
(define-binary-check (check-my-equal? my-equal? actual expected))

因为这不会执行递归检查。

我可以自己处理递归,并且只对原语使用equal?,但这对于实现自己的一致性测试至关重要。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-12 17:37:34

您可以使用equal?/recur来获取这种行为。该函数的行为类似于equal?,但在递归调用的情况下则采用不同的函数。因此,您可以这样实现my-equal?

代码语言:javascript
复制
(define (my-equal? actual expected)
  (if (and (syntax? actual) (syntax? expected))
      (equal? (syntax->datum actual) (syntax->datum expected))
      (equal?/recur actual expected my-equal?)))

但是,请注意,由于您提供的是递归函数,所以equal?/recur不会为您执行任何周期检测。因此,你需要自己去做。一个简单的方法是使用参数:

代码语言:javascript
复制
(define current-equal-visited (make-parameter set))
(define (my-equal? actual expected)
  (cond [(set-member? (current-equal-visited) (cons actual expected))
         #t]
        [(and (syntax? actual) (syntax? expected))
         (equal? (syntax->datum actual) (syntax->datum expected))]
        [else
         (parameterize ([current-equal-visited
                         (set-add (current-equal-visited) (cons actual expected))])
           (equal?/recur actual expected my-equal?))]))

当然,正如您在问题中所注意到的,您可以使用define-binary-check将这个过程转化为RackUnit可以实现的功能。

代码语言:javascript
复制
(define-binary-check (check-my-equal? my-equal? actual expected))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37193760

复制
相关文章

相似问题

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