2016-11-17 7 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

Как раз в сторону, всякий раз, когда у меня была проблема, и я решил использовать «ценности» для ее решения, я столкнулся с двумя проблемами и переписал код для предоставления списка или строки, кажется, более простой код. –

ответ

1

values Поскольку возвращается multiple 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

Вы можете конвертировать несколько значений в виде списка, а затем сравнить его с ожидаемыми значениями:

(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. Практически он работает почти так же, как list и apply, но без создания минусов между ними. Таким образом, его просто оптимизация. В реализации, использующей стек, она возвращает значения в стеке, и call-with-values будет применяться только с тем же фреймом, который он получил от применения thunk.

Я действительно думаю, что версия Common Lisp более полезна, так как позволяет использовать несколько процедур оценки стоимости в ситуациях с одним значением только при использовании первого значения. На диалектах Scheme вам нужно использовать call-with-values или макрос или процедуру, которая использует его для обработки нескольких значений, что менее гибко, но, возможно, может выполнять другие вызовы немного более эффективно.

Смежные вопросы