Введите вывод и новый в F # - PullRequest
6 голосов
/ 16 июня 2011

Используя 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?

Теперь есть что-то, что я разумно могу сделать?Почему я должен выбирать между рабочим типом вывода или свободным кодом предупреждений (если «Список» одноразовый, вы получаете предупреждение о том, что вам следует использовать «новый», чтобы явно указать это).

Любой обходной путь?Это ошибка или что-то в этом роде?

Ответы [ 2 ]

13 голосов
/ 16 июня 2011

Вы все еще можете использовать вывод типа с подстановочным знаком _:

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

let bar = new List<_>(xs)

Кстати, чтобы различать список F # и контейнер .NET List<T>, F # переименовал .NET List<T> в ResizeArray<T>, который находится в Microsoft.FSharp.Collections, и это пространство имен открывается по умолчанию:

let bar2 = new ResizeArray<_>(xs)
8 голосов
/ 16 июня 2011

Инь Чжу ответ правильный, я бы хотел добавить одну деталь.В F # вы можете вызывать конструкторы .NET с ключевым словом new или без него.Если 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
...