3

我在 Racket 中写了一个免费的乘以进位 PRNG。我想用它provide来限制对我库中某些功能的访问,并对它们强加合同。使用球拍文档(上面链接),我已将以下代码放在我的文件顶部为此:

(require data/queue)
(provide 
 (contract-out
  (make-cmwc-gen (-> (listof integer?) integer? integer? integer? procedure?))
  (make-default-cmwc-gen (-> integer? procedure?))
  (make-cmwc-gen-raw (-> queue? integer? integer? integer? procedure?))
  (init-cmwc-seed (-> integer? queue?)))) 

但是当我在 DrRacket 中运行该文件时,出现以下错误:

. contract-out: not a provide sub-form in: (contract-out (make-cmwc-gen (-> (listof 
integer?) integer? integer? integer? procedure?)) (make-default-cmwc-gen (-> integer?   
procedure?)) (make-cmwc-gen-raw (-> queue? integer? integer? integer? procedure?)) 
(init-cmwc-seed (-> integer? queue?)))

该代码在没有插入上述代码的情况下在 DrRacket 中运行时不会引发错误,并且可以正常工作。

限制仅访问源文件之外的某些功能以及在 Racket 中执行合同的正确方法是什么?

4

1 回答 1

7

contract-out是新的,并在 Racket 5.2 中引入。如果您使用的是 Racket < 5.2,您仍然可以使用provide/contract

例子:

#lang racket
(provide/contract [f (-> number? number?)])

(define (f x) 42)

在 Racket 5.2 中,contract-out首选是因为合约中的元素可以在合约之后定义。也就是说,如果你在旧系统中尝试这样的事情,

#lang racket
;; The following will fail since the contract definition doesn't know
;; about p? at the point of its definition.
(provide/contract [f (-> p? p?)])

(define p? number?)
(define (f x) 42)

那么它会失败,因为p?是在合同之后定义的。

相反,contract-out无需重新排列定义即可工作:

#lang racket
(provide (contract-out [f (-> p? p?)]))

(define p? number?)
(define (f x) 42)
于 2011-12-22T19:37:26.440 回答