Определение контрактов на ракетку с помощью пользовательского предиката
Я только начинаю узнавать о контрактах (через exercism.io), и поэтому я заключил контракт, который:
[step1 (-> (and/c number?
less-than-one-hundred?)
string?)]
То, что я думаю, я говорю, что функция будет принимать число меньше ста (эта функция определяется как:
(define (less-than-one-hundred? n)
(< n 100))
Но когда я вызываю функцию так:
(step1 100)
Нет нарушения договора. Что я делаю неправильно?
2 ответа
Вот конкретный пример того, что говорит ответ Soegaard:
DEF-step1.rkt
#lang racket
(provide (contract-out
[step1 (-> (and/c number?
less-than-one-hundred?)
string?)]))
(define (less-than-one-hundred? n)
(< n 100))
(define (step1 x) "")
потребительная step1.rkt
#lang racket
(require "def-step1.rkt")
(step1 100)
Это приводит к нарушению контракта, как вы ожидаете, и, в частности, он обвиняет use-step1.rkt
, другая "сторона контракта", чем def-step1.rkt
откуда пришел контракт:
step1: contract violation
expected: less-than-one-hundred?
given: 100
in: an and/c case of
the 1st argument of
(->
(and/c number? less-than-one-hundred?)
string?)
contract from: .../def-step1.rkt
blaming: .../use-step1.rkt
(assuming the contract is correct)
Контракты применяются только через границы модуля. Это означает, что если ваше выражение (step1 100)
находится в том же модуле, что и контракт, вход не проверяется.
Однако если вы экспортируете step1
с контрактом, а затем в другом модуле импорта step1
и называет его, договор будет проверен.