2013-04-05 30 views
3

據我所知,值定義中的顯式類型參數是克服「價值限制」問題的一種方法。
我還需要使用它們嗎?
什麼是F#顯式類型參數的用例?

UPD:我的意思是「顯式通用構建體」,其中類型參數被尖括號括起來,即

let f<'T> x = x 
+0

只是要清楚,你的意思類型參數(在定義),或輸入參數(在使用點)? – 2013-04-05 13:20:06

回答

3

這很可能是罕見的,但是當你想防止進一步泛化(§14.6.7):

Explic它在值上鍵入參數定義,並且成員定義可以影響類型推斷和泛化的過程。特別是,包含顯式泛型參數的聲明不會超出這些泛型參數。例如,考慮這樣的功能:

let f<'T> (x : 'T) y = x 

在類型推斷,這將導致以下類型,其中「_b是一種類型推斷變量是有待解決的一個功能。

f<'T> : 'T -> '_b -> '_b 

爲了允許概括在這些定義中,或者刪除明確的通用參數(如果它們可以推斷),或者使用所需要的數量的參數,如下面的示例示出了:

let throw<'T,'U> (x:'T) (y:'U) = x 

當然,你也可以通過類型註釋來完成。

1

最明顯的例子:寫一個函數來計算串的長度。

你必須寫:

let f (a:string) = a.Length 

,你需要註釋。如果沒有註釋,編譯器無法確定a的類型。還有其他類似的例子 - 特別是使用C#中使用的庫時。

使用更新的答案處理:

同樣的問題適用 - string成爲A<string>其中有一個方法get返回一個string

let f (a:A<string>) = a.get().Length 
+0

請參閱更新;問題是關於類型參數(不是鍵入註釋) – 2013-04-05 03:03:23

+0

@JohnRivers - 查看更新的答案 – 2013-04-05 03:06:08

5

多態遞歸是另一種情況。也就是說,如果你想在函數體內使用不同的泛型實例,那麼你需要在定義中使用明確的參數:

// perfectly balanced tree 
type 'a PerfectTree = 
| Single of 'a 
| Node of ('a*'a) PerfectTree 

// need type parameters here 
let rec fold<'a,'b> (f:'a -> 'b) (g:'b->'b->'b) : 'a PerfectTree -> 'b = function 
| Single a -> f a 
| Node t -> t |> fold (fun (a,b) -> g (f a) (f b)) g 

let sum = fold id (+) 

let ten = sum (Node(Node(Single((1,2),(3,4))))) 
相關問題