使用自定义谓词定义球拍合同
Defining racket contracts with a custom predicate
我刚刚开始了解合同(通过 exercism.io),所以我制定了一份合同:
[step1 (-> (and/c number?
less-than-one-hundred?)
string?)]
我认为我的意思是该函数将采用小于一百的数字(该函数定义为:
(define (less-than-one-hundred? n)
(< n 100))
但是当我这样调用函数时:
(step1 100)
没有违约。我做错了什么?
合同仅在模块边界上强制执行。
这意味着如果您的表达式 (step1 100)
与您的合同在同一个模块中,则不会检查输入。
但是,如果您使用合同导出 step1
,然后在另一个模块中导入 step1
并调用它,则会检查合同。
以下是 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
,"contract party" 与 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)
我刚刚开始了解合同(通过 exercism.io),所以我制定了一份合同:
[step1 (-> (and/c number?
less-than-one-hundred?)
string?)]
我认为我的意思是该函数将采用小于一百的数字(该函数定义为:
(define (less-than-one-hundred? n)
(< n 100))
但是当我这样调用函数时:
(step1 100)
没有违约。我做错了什么?
合同仅在模块边界上强制执行。
这意味着如果您的表达式 (step1 100)
与您的合同在同一个模块中,则不会检查输入。
但是,如果您使用合同导出 step1
,然后在另一个模块中导入 step1
并调用它,则会检查合同。
以下是 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
,"contract party" 与 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)