球拍:在合同中使用的自定义谓词

Boh*_*nov 3 scheme date predicate contract racket

我正在用球拍编写小型宠物项目,并使用Gregor lib处理日期。

我有接受两个日期(来自Gregor,而不是标准库)的函数,我想为其添加合同。合同应该说,第一个参数的日期必须小于/早于第二个参数的日期。

在Gregor中,我们可以使用(date <=?xy)或类似谓词来实现它,但是我不明白如何将其与合同结合使用。

 (contract-out
          [process-dates (->i ([x date?]
                               [y (x) (and/c date?
                                             (date>=? x))])])
Run Code Online (Sandbox Code Playgroud)

将不起作用,并且没有现成的date>=?/c谓词。

因此,我想我需要自己编写这样的谓词,因此我想知道如何去做。我已经通过球拍来源看,发现标准功能是相当复杂的重现。

有更简单的方法来实现我想要的吗?

Rya*_*per 5

最简单的方法是使用lambda

(->i ([x date?]
      [y (x) (and/c date? (lambda (y) (date>=? y x)))])
     [_ any/c])
Run Code Online (Sandbox Code Playgroud)

一个缺点是,如果违反合同,则错误消息将包含一个???代替lambda表达式的消息。如果您希望它在此处打印出更有意义的内容,则可以执行以下操作:

(define (date>=/c x)
  (flat-named-contract
   `(date>=/c ,x)
   (lambda (y) (date>=? y x))))
....
(->i ([x date?]
      [y (x) (and/c date? (date>=/c x))])
     [_ any/c])
Run Code Online (Sandbox Code Playgroud)

如果您想更好地控制错误消息,可以尝试使用flat-contract-with-explanation