我在Racket中写过一个免费乘法携带的PRNG。我想使用provide
来限制只访问我的库中的某些功能,以及to impose contracts on them。使用Racket文档(上面链接),我已将以下代码放在我的文件顶部:
(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中强制执行合同的正确方法是什么?
答案 0 :(得分: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)