2016-11-17 39 views
1

私はRacketとDr. Racketを教育目的で使用しています。Rackunitでのこのテストはなぜ機能しませんか?

私はvaluesビルトイン機能を理解しようとしています。

私は、次の入力を使用して値を呼び出すと、私はこの出力を得る:

> (values 'this 'and-this 'and-that) 
'this 
'and-this 
'and-that 

なぜこのテストが失敗するのか?それを扱うことができない

#lang racket 

(require rackunit racket/trace) 

(check-equal? (values 'this 'and-this 'and-that) 'this 'and-this 'and-that) 
+1

問題を抱えて解決するために値を使うことに決めたときは、2つの問題があり、コードを書き直してリストを作成するか、文字列を必要とせず、簡単なコード。 –

答えて

1

valuesmultiple valuesを返しているので、とcheck-equal?は、それが正確に二つの値を比較することで期待しています。

(check-equal? (values 42) 42) 

のは、我々が最初に複数の値を展開し、リストに入れましょう、別のアプローチを試してみてください:

(check-equal? 
(let-values ([(a b c) (values 'this 'and-this 'and-that)]) 
    (list a b c)) 
'(this and-this and-that)) 
1

我々は2つだけの値を扱っているので、例えば、これは動作しますリストには複数の値を変換して、期待値と比較することができます:

(define-syntax values->list 
    (syntax-rules() 
    ((_ expr) 
    (call-with-values (lambda() expr) 
         list)))) 

(check-equal? (values->list (values 'this 'and-this 'and-that)) 
       (list 'this 'and-this 'and-that)) 

valuesは非常に特別です。それはcall-with-valuesと結びついています。実際にはlistapplyとほとんど同じですが、その間に短所を作ることはありません。従ってそのちょうど最適化。スタックを使用する実装では、スタック上の値を返し、call-with-valuesは、サンクを適用したときと同じフレームで適用されます。

私はCommon Lispバージョンが、最初の値だけが使用されている単一値の状況で複数の値のプロシージャを使用できるようにするので、より便利だと思います。 Scheme方言では、call-with-valuesを使用するか、複数の値を処理するためにそれを使用するマクロまたはプロシージャを使用する必要があります。これは、柔軟性は低くなりますが、他の呼び出しを有効にすることができます。

関連する問題