2016-03-29 4 views
2

Скажем, у меня есть функция:Racket - может ли контракт на аргумент функции зависеть от значения другого аргумента?

(define (func x y) 
    ...) 

Я хотел бы ограничить аргументы, так что:

  • х является положительным целым числом
  • у является положительным целым числом, которое меньше или равно x

Первое ограничение, очевидно, тривиально, но есть ли способ установить второе ограничение с помощью контрактной системы Ракетта?

ответ

5

Да. Вы хотите использовать зависимые контракты, в Ракетке, выраженной с помощью комбинатора контрактов ->i. Контракт на вашей функции, как вы описали это будет выглядеть следующим образом:

(->i ([x (and/c integer? positive?)] 
     [y (x) (and/c integer? positive? (<=/c x))]) 
    [result any/c]) 

Вот пример такого рода ошибки, которые возникают при ненадо применения функции по контракту с указанным контрактом:

> (func 1 2) 
func: contract violation 
    expected: (and/c integer? positive? (<=/c 1)) 
    given: 2 
    in: the y argument of 
     (->i 
     ((x (and/c integer? positive?)) 
     (y 
     (x) 
     (and/c integer? positive? (<=/c x)))) 
     (result any/c)) 
    contract from: (function func) 

Для зависимых контрактов все аргументы и результат нужно называть так, чтобы их можно было ссылаться в других предложениях. (x) в статье второго аргумента указывает, что договор для yзависит от от x, поэтому вы можете использовать x в спецификации контракта для y.

Полная грамматика для ->i доступна in the documentation, которая имеет множество дополнительных функций. В нем также есть некоторые примеры, в том числе такие, которые очень похожи на пример в вашем вопросе.

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

  • Нет связанных вопросов^_^