Да. Вы хотите использовать зависимые контракты, в Ракетке, выраженной с помощью комбинатора контрактов ->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, которая имеет множество дополнительных функций. В нем также есть некоторые примеры, в том числе такие, которые очень похожи на пример в вашем вопросе.