Racket - 函数参数的契约是否可以依赖于另一个参数的值?

Chr*_*Vig 2 contract racket

假设我有一个功能:

(define (func x y)
    ...)
Run Code Online (Sandbox Code Playgroud)

我想约束这些论点,以便:

  • x是正整数
  • y是小于或等于x的正整数

第一个约束显然是微不足道的,但有没有办法用Racket的合同系统设置第二个约束?

Ale*_*ing 5

是.您想使用合同组合器表达的Racket中的依赖合同->i.您描述的函数合同将如下所示:

(->i ([x (and/c integer? positive?)]
      [y (x) (and/c integer? positive? (<=/c x))])
     [result any/c])
Run Code Online (Sandbox Code Playgroud)

以下是不恰当地应用与上述合同约定的功能时可能发生的错误的示例:

> (func 1 2)
func: contract violation
  expected: (and/c integer? positive? (<=/c 1))
  given: 2
  in: the y argument of
      (->i
       ((x (and/c integer? positive?))
        (y
         (x)
         (and/c integer? positive? (<=/c x))))
       (result any/c))
  contract from: (function func)
Run Code Online (Sandbox Code Playgroud)

对于从属合同,需要对所有参数和结果进行命名,以便可以在其他子句中引用它们.在(x)第二个参数中的子句指定的合同y 取决于价值x,所以你可以使用x在合同规定范围内y.

文档中->i提供完整的语法,其中包含许多其他功能.它还有一些示例,包括与您的问题中的示例非常相似的示例.