Я пытаюсь реализовать арифметику в поле по модулю N. Вот упрощенный пример:
(struct field-element (number prime) #:transparent)
(define (field-element-add fe1 fe2)
(field-element (modulo (+ (field-element-number fe1)
(field-element-number fe2))
(field-element-prime fe1))
(field-element-prime fe1)))
(field-element-add (field-element 3 5) (field-element 4 5)) ; (1)
(field-element-add (field-element 3 5) (field-element 4 6)) ; (2)
(1) должно вернуть (field-element 2 5)
, потому что 3 + 4 = 7 = 2 mod 5
(2) должно вызвать ошибку, потому что вы не можете добавлять элементы в поля с другим модулем простого числа (в этом примере 5 и 6).
Мой вопрос: как использовать контракты, которые проверяют все аргументы для field-element-add
, совместно используют один и тот же prime
и вызывают ошибки, когда их нет?
Все контракты, которые я видел в документах , вводят ограничения для каждого аргумента в отдельности, например, integer?
. Но я хочу применить ограничение к аргументам как к группе: они должны иметь общее свойство prime
.
И я знаю, что я мог бы просто проверить это вручную без контракта, но похоже, что именно для этого были заключены контракты на обстоятельства.
Заранее спасибо!