2016-05-12 9 views
3

check-equal?を使用して、eq?以外の構文オブジェクトを含むオブジェクトを使用して一連のテストを作成しています。これらのテストでは、syntax->datumに与えられたときに等しい場合、2つの構文オブジェクトが等しいと言っても大丈夫です。 (バインディング情報がたくさんあることは分かりますが、現在ではデータの平等性を保証しています)バインド情報が後で良いことをテストします。RackUnitで使用する修正された `equal?`関数を作成します

2つのオブジェクトが構文オブジェクトしかし、私は彼らがお互いにequal?であれば、彼らが平等であることを望みます。

これらのオブジェクトは、いくつかの再帰的な時点でそれらの構文のオブジェクトが含まれている場合は、私は彼らのデータム上の平等をテストしたいので、私はちょうど行うことはできません。

(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?しか使用できませんでしたが、それは自分自身の等価性テストを実装する上で最も重要なことです。

答えて

1

equal?/recurを使用すると、この現象が発生します。この関数はequal?のように動作しますが、再帰呼び出しの場合は別の関数を使用します。ですから、潜在的にこのようなmy-equal?を実現することができます。

(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はあなたのための任意のサイクル検出を行いませんのでご注意します。そのように、あなたはそれを自分で行う必要があります。

(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?))])) 

そして、あなたはあなたの質問に気づいたとして、その後、もちろん、あなたがRackUnitすることができます何かにこの手順を有効にするdefine-binary-checkを使用することができます。これを行う1つの簡単な方法は、パラメータです。

(define-binary-check (check-my-equal? my-equal? actual expected)) 
関連する問題