【问题标题】:Defining racket contracts with a custom predicate使用自定义谓词定义球拍合约
【发布时间】:2018-11-18 12:53:56
【问题描述】:

我刚刚开始了解合同(通过 exercism.io),所以我签订了一份合同:

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

认为我的意思是该函数将采用小于 100 的数字(该函数定义为:

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

但是当我这样调用函数时:

(step1 100)

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

【问题讨论】:

    标签: racket contract


    【解决方案1】:

    以下是 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) "")
    

    use-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)
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-30
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多