2012-07-29 63 views
1

我很不解,爲什麼第三個功能是行不通的:值限制的情況下在F#

let generate1 = id 
    let generate2 = let a = 1 
        id 
    let generate3 = printfn "hi" 
        id 

而第2都很好,最後一個吐出

error FS0030: Value restriction. The value 'generate3' has been inferred to have generic type 
    val generate3 : ('_a -> '_a)  
Either make the arguments to 'generate3' explicit or, if you do not intend for it to be generic, add a type annotation. 

回答

6

我贏了」試圖explain value restriction,但我會試圖理清這三個值之間的語義差異。

generate1只是id的別名,所以我們很好。

generate3在返回id之前做了一些計算,達到了數值限制。

那麼爲什麼不generate2generate3命中限制?因爲編譯器可以看到let x = 1 in id在語義上等同於id1是一個常量表達式,並且x未在let ... in ...表達式的主體中使用,因此編譯器可以將它們丟棄。另一方面,如果用代替sin 2.3這樣的潛在副作用(sin是純的,但編譯器無法證明它),那麼編譯器不能安全地減少表達式,從而達到值限制與generate3一樣。

+0

有罪的例子。價值限制和可證明的副作用之間的聯繫對我來說並不是微不足道的。我不會把這樣的錯誤信息methink。 – nicolas 2012-07-29 14:52:04