Как использовать контракт в Racket - PullRequest
3 голосов
/ 22 декабря 2011

Я написал приветственный PRNG с умножением при переноске в Racket. Я хочу использовать provide для ограничения доступа только к определенным функциям в моей библиотеке и для наложения на них контрактов . Используя Racket Documentation (ссылка выше), я поместил следующий код в начало моего файла с этой целью:

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

1 Ответ

7 голосов
/ 22 декабря 2011

contract-out является новым и представлен в Racket 5.2.Если вы используете Racket <5.2, вы все равно можете использовать <a href="http://docs.racket-lang.org/reference/Attaching_Contracts_to_Values.html#%28form._%28%28lib._racket/contract/private/provide..rkt%29._provide/contract%29%29" rel="nofollow">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)
...