2012-07-22 39 views
3

模塊:測試define.rkt球拍模塊的合同讓我困惑

#lang racket 

(provide test) 

(provide (contract-out [add-test! (-> void)])) 

(define test 0) 

(define (add-test!) 
    (set! test (add1 test))) 

主程序:act.rkt

#lang racket 

(require "test-define.rkt") 

(printf "~a~%" test) 

(add-test!) 

(printf "~a~%" test) 

運行act.rkt,我得到:

0 
1 

這是我想要的。

但是,如果我改變測試define.rkt合同:

(provide test) 

變化

(provide (contract-out [test integer?])) 

然後我再次運行act.rkt,我得到:

0 
0 

爲什麼?我無法更改測試值。

如果我提供了一個get func,它會再次變爲正常。

(provide (contract-out [get-test (-> integer?)])) 

(define (get-test) 
    test) 

如果測試的類型更改爲哈希映射,則總是正常的。

我錯過了什麼?

回答

4

我注意到,在測試define.rkt你有這條線

(set! test3 (add1 test)) 

應該test3test

這可能可以解釋爲什麼你看到了兩個零(測試從未改變過)。

EDIT 2

爲了方便起見,我把你的兩個模塊在同一個文件 ,改變測試的合同:

#lang racket 
(module test-define racket 
    (provide test) 
    ; (provide (contract-out [test integer?])) 
    (provide get-test) 
    (provide (contract-out [add-test! (-> void)])) 
    (define test 0) 
    (define (add-test!) 
    (set! test (add1 test))) 
    (define (get-test) 
    test)) 

(module ack racket 
    (require (submod ".." test-define)) 
    (printf "~a~%" test) 
    (add-test!) 
    (printf "~a~%" test)) 

(require (submod "." ack)) 

現在我看到了0 1比0 0輸出爲你做。

嗯。爲什麼?

好吧。如果我們更改提供表單,根本沒有使用合同 ,則輸出爲0 1.

添加合同不應改變此行爲(我認爲)。 也許是一個錯誤?

http://pre.racket-lang.org/docs/html/guide/contracts-gotchas.html?q=contract&q=ignore

說:

合同庫假定通過外判 出口變量不分配,但不強制執行。因此,如果你嘗試 設置!這些變量,你可能會感到驚訝。 ...略...道德:這 是我們將在未來版本中解決的一個錯誤。

+0

感謝您的回答,這是我的第一個stackoverflow答案!但是這是我的類型錯誤,我已經修復它。這個問題讓我困惑,是一些基本理論的球拍模塊或合同我不喘氣? – simmone 2012-07-22 12:35:32

+0

我無法運行你的ack.rkt,因爲它在上面。缺少'get-test'的定義。 – soegaard 2012-07-22 13:27:12

+0

非常抱歉,我再次輸入錯誤。它應該是:(printf「〜a〜%」測試),我的球拍版本是5.2.1。感謝您的回覆,我期待您的回答。 – simmone 2012-07-22 13:42:35