2014-05-22 76 views
1

我已經創建了一個返回只包含偶數索引列表的功能,如下圖所示:爲什麼會產生價值限制例外?

let rec removeOddIdx xs = 
    match xs with 
    |[] -> [] 
    |h::t -> (if t.Length % 2 = 0 then 
       [h]@removeOddIdx t 
       else 
       removeOddIdx t) 

它正常工作時,我把它叫做:

removeOddIdx [1;2;3;];; 

然而,當我把它用空列表:

removeOddIdx [];; 

我得到一個Value Restriction異常 - 怎麼回事?
我讀過價值限制,但我不明白爲什麼發生在我的情況。

這裏是精確的錯誤消息:

Testing.fs(13,1):錯誤FS0030:值限制。值'it'已經被推斷爲有通用型

          val it : '_a list

要麼定義'it'一個簡單的數據來看,使它成爲一個功能有明確的參數,或者,如果你不爲她打算是通用的,添加一個類型註釋。

+1

嗯,我試過了,但我沒有得到任何異常,編譯器錯誤或警告。 –

+0

這很奇怪。每次運行它時,我都會收到錯誤(使用錯誤文本更新了線程)。 – user3665877

回答

1

你遇到的問題是編譯器不知道什麼類型給予返回值。當你通過它[1;2;3]它可以推斷返回類型是int list,但如果你通過它[],返回值的類型是什麼?它不能從使用情況推斷,所以你會得到一個價值限制錯誤。

一種解決方案是給該參數的類型,像這樣:

> removeOddIdx ([]:int list);; 
val it : int list = [] 

另一種方法是使特定功能而不是一般的像這樣:

> let rec removeOddIdx (xs:int list) = 
    match xs with 
    |[] -> [] 
    |h::t -> (if t.Length % 2 = 0 then 
       [h]@removeOddIdx t 
       else 
       removeOddIdx t);; 

val removeOddIdx : xs:int list -> int list 

> removeOddIdx [];; 
val it : int list = [] 

外REPL的,這是不太可能成爲問題,因爲參數類型可能會從代碼中的其他地方推斷出來。

+0

啊我現在明白了。非常感謝你對它的解釋! – user3665877

+0

@ user3665877沒問題! – mydogisbox

相關問題