Определение контрактов на ракетку с помощью пользовательского предиката - PullRequest
0 голосов
/ 18 ноября 2018

Я только начинаю узнавать о контрактах (через exercism.io), и поэтому я заключил контракт, который:

[step1 (-> (and/c number?
                  less-than-one-hundred?)
            string?)]

Что я думаю Я говорю, что функция будет принимать число меньше ста (это функция, определенная как:

(define (less-than-one-hundred? n)
  (< n 100))

Но когда я вызываю функцию следующим образом:

(step1 100)

Нет нарушения договора. Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Вот конкретный пример того, что говорит ответ Сойгаарда:

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)
0 голосов
/ 18 ноября 2018

Контракты применяются только через границы модуля. Это означает, что если ваше выражение (step1 100) находится в том же модуле, что и ваш контракт, ввод не проверяется.

Однако, если вы экспортируете step1 с контрактом, а затем в другой модуль импортируете step1 и вызываете его, контракт будет проверен.

...