使用自定义谓词定义racket契约

使用自定义谓词定义racket契约,racket,contract,Racket,Contract,我刚刚开始通过exercism.io了解合同,因此我签订了一份合同: [step1 (-> (and/c number? less-than-one-hundred?) string?)] 我想说的是,这个函数将取一个小于100的数字,这是一个定义为: (define (less-than-one-hundred? n) (< n 100)) 没有违反合同。我做错了什么?合同仅在模块边界上强制执行。 这意味着,如果您

我刚刚开始通过exercism.io了解合同,因此我签订了一份合同:

[step1 (-> (and/c number?
                  less-than-one-hundred?)
            string?)]
我想说的是,这个函数将取一个小于100的数字,这是一个定义为:

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

没有违反合同。我做错了什么?

合同仅在模块边界上强制执行。 这意味着,如果您的表达式Step1100与合同位于同一模块中,则不会检查输入


但是,如果您使用协定导出step1,然后在另一个模块中导入step1并调用它,则将检查协定。

协定仅在模块边界上强制执行。 这意味着,如果您的表达式Step1100与合同位于同一模块中,则不会检查输入


但是,如果您使用合同导出step1,然后在另一个模块中导入step1并调用它,则会检查合同。

以下是Soegaard回答的具体示例:

def-step1.rkt

这导致了与您预期的一样的合同违约,特别是,它将责任归咎于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)

下面是一个具体的例子,说明Soegaard的答案是什么:

def-step1.rkt

这导致了与您预期的一样的合同违约,特别是,它将责任归咎于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)
#lang racket

(require "def-step1.rkt")

(step1 100)
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)