Racket - 函数参数的合同可以依赖于另一个参数的值吗?

Racket - can a contract on a function argument depend on the value of another argument?

假设我有一个函数:

(define (func x y)
    ...)

我想限制参数以便:

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

是的。您想在 Racket 中使用 依赖合约 ,使用 ->i 合约组合器表示。您所描述的函数合同如下所示:

(->i ([x (and/c integer? positive?)]
      [y (x) (and/c integer? positive? (<=/c x))])
     [result any/c])

以下是错误应用上述合约约定的函数时会发生的错误类型的示例:

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

对于从属合同,所有参数和结果都需要命名,以便在其他条款中引用它们。第二个参数子句中的 (x) 指定 y 的合同取决于 x 的值,因此您可以使用 xy.

的合同规范中

->i 的完整语法可用 in the documentation,其中有许多附加功能。它也有一些示例,包括一个与您问题中的示例非常相似的示例。