如何在Racket中使用合同

djh*_*987 3 contract prng racket

我在Racket中写了一个免费乘法携带的PRNG.我想用来provide限制只访问我的库中的某些功能,并对它们施加合同.使用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?)))) 
Run Code Online (Sandbox Code Playgroud)

但是当我在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?)))
Run Code Online (Sandbox Code Playgroud)

代码抛出没有错误,否则在DrRacket中运行时没有插入上面的代码.

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

dyo*_*yoo 7

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

例:

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

(define (f x) 42)
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

然后它失败了,因为p?在合同之后定义了.

相比之下,contract-out工作无需重新排列定义:

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

(define p? number?)
(define (f x) 42)
Run Code Online (Sandbox Code Playgroud)