2011-06-16 76 views
6

使用F#2.0 FSI我有以下幾點:類型推斷和新的 - 我可能只是愚蠢

let foo = List(xs)//works 
let bar = new List(xs) //need type parameter 'The type System.Collectsion.Generic<_> expects 1 type argument 0 was given 

現在我當然可以這樣做:

let baz = new List<TypeOItemsInXs>(xs)//why? 

現在是有什麼我合理可以做到嗎? 爲什麼我必須在工作類型推理或警告免費代碼之間進行選擇(如果'List'是一次性的,您會得到一個警告,您應該使用'new'來明確它)。

任何解決方法?這是一個錯誤還是什麼?

回答

13

,您仍然可以使用類型推斷使用通配符_

open System.Collections.Generic 
let xs = [1;2;3] 

let bar = new List<_>(xs) 

BTW,區分F#列表和.NET List<T>容器,F#已經改名爲.NET List<T>ResizeArray<T>,這是Microsoft.FSharp.Collections,這命名空間默認打開:

let bar2 = new ResizeArray<_>(xs) 
8

尹竺的回答是對的,我想補充一個細節。在F#中,您可以調用帶有或不帶有new關鍵字的.NET構造函數。如果省略了new,則不需要添加通用參數,但如果使用new,則必須添加通用參數,即使您讓類型推斷使用通配符_來完成工作。

因此,你可以說:

> ResizeArray([1; 2; 3;]);; 
val it : System.Collections.Generic.List<int> = seq [1; 2; 3] 

> new ResizeArray<_>([1; 2; 3;]);; 
val it : ResizeArray<int> = seq [1; 2; 3] 

但不是:

> new ResizeArray([1; 2; 3;]);; 

    new ResizeArray([1; 2; 3;]);; 
    ----^^^^^^^^^^^ 

C:\Temp\stdin(5,5): error FS0033: The type 'Microsoft.FSharp.Collections.ResizeArray<_>' expects 1 type argument(s) but is given 0 
+0

IMO這是更好的。 'new'是多餘的。 – Daniel 2011-06-16 14:19:01

+0

另外,我認爲新的應該與use關鍵字一起使用,當你創建一個IDisposable時,否則它應該被省略。 – Alex 2011-06-16 14:42:27

+1

是的,我的問題是我有一次性類型,並省略新的警告。如果我添加新的話,那麼尹如指出可以用通配符逃脫。這種語言是不對稱的:S – 2011-06-16 15:02:19