Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type inference & new in F#

Using F# 2.0 and FSI I have the following:

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

now of course I can do:

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

Now is there something I reasonably can do? Why do I have to choose between working type inference or warnings free code (if 'List' is disposable you get a warning that you should use 'new' to be explicit about it).

Any workaround? Is this a bug or something?

like image 246
Torbjörn Gyllebring Avatar asked Jun 16 '11 11:06

Torbjörn Gyllebring


People also ask

What is type interference?

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.

What is type inference in Java?

Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.

What is type inference in Python?

Type inference for dynamic programming languages such as Python is an important yet challenging task. Static type inference tech- niques can precisely infer variables with enough static constraints but are unable to handle variables with dynamic features.

What is type inferred language?

Type inference is often a compiler feature of functional programming languages rather than of object-oriented ones. The compiler or interpreter needs only minimal information as well as context in order to figure out what the data type of a variable or expression is.


2 Answers

You can still use type inference with a wildcard _:

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

let bar = new List<_>(xs)

BTW, to distinguish F# list and .NET List<T> container, F# has renamed the .NET List<T> to ResizeArray<T>, which is in Microsoft.FSharp.Collections and this namespace is opened by default:

let bar2 = new ResizeArray<_>(xs)
like image 123
Yin Zhu Avatar answered Nov 01 '22 14:11

Yin Zhu


Yin Zhu answer is correct, I'd like to add one detail. In F# you can call .NET constructors with or without the new keyword. If new is omitted there's no need to add the generic parameter, but if you use new then you must add a generic parameter, even if you let type inference do the work using a wildcard _.

Thus, you can say:

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

or

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

but not:

> 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
like image 29
Robert Avatar answered Nov 01 '22 13:11

Robert