2011-06-07 36 views
2

如果我有一個函數定義爲任何避免這種類型推斷問題的方法?

let test = function 
    | [] -> None 
    | head::tail -> Some(head) 

FSI可以讓我定義這個編譯就編譯它;但如果我真的試圖做test [],它會崩潰。

現在我知道推理,當我給它一個空集,它不能推斷類型,所以通用函數失敗,但它可以做一些有點聰明嗎? (沿着「我不知道'a的類型,但在這種情況下,我不使用'a,所以我打算允許這樣做」)。這個問題?

回答

2

有一個偉大的article about value restriction MSDN和additional notes about tricky aspects布賴恩,詳細解釋這個問題。

當您編寫test []時,結果的類型爲option<'a>,因此編譯器需要知道要使用的類型來代替'a。您實際上並未使用類型'a的值,但編譯器需要編譯使用它的代碼。 F#不允許使用通用值(一般),因此該值需要具體的類型。

您可以編寫類似:

let foo() = test [] 

這是unit -> option<'a>類型的標準通用功能,所以這是一個完全有效的結構。您還可以使用類型批註指定結果明確的類型:

(test []:option<obj>) 
+0

很好的類型,你可以寫讓foo()= test [] - 但當你試圖執行它時,foo仍然會出錯...那裏的樂趣在哪裏?標記爲答案因爲指定obj看起來像是唯一的方法。 – Massif 2011-06-07 14:01:32

+2

@Massif - 問題是,你想如何使用結果,輸入列表從哪裏來?在任何實際的例子中,你都會在一些指定類型的上下文中使用代碼。 (Brian的文章中的部分函數應用程序示例並非如此,但是您的代碼可能會出現在更廣泛的上下文中。) – 2011-06-07 14:04:27

+0

這很可能是真的 – Massif 2011-06-07 14:06:22

-1

確實把[]情況最後會做到這一點?

+0

爲什麼會作出任何區別,我還沒有告訴它「一個...... – Massif 2011-06-07 13:59:18