Massif
Massif

Reputation: 4433

Any way of avoiding this type inference problem?

If I have a function defined as

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

fsi will allow me to define this and the compile will compile it; but it will fall over should I ever actually try to do test [].

Now I know the reasoning, when I give it an empty set it can't infer the type and so the generic function fails, but can it not do something a bit cleverer? (along the lines of, "I don't know the type of 'a but in this case I'm not using 'a so I'm going to allow this.")

Anyway, is there any way I can avoid this problem?

Upvotes: 2

Views: 133

Answers (2)

Tomas Petricek
Tomas Petricek

Reputation: 243041

There is a great article about value restriction on MSDN and additional notes about tricky aspects by Brian that explains this problem in details.

When you write test [] the result has a type option<'a>, so the compiler needs to know the type to be used in place of 'a. You're not actually using values of type 'a, but the compiler needs to compile the code that uses it. F# doesn't allow working with generic values (in general) so the value needs to have concrete type.

You can write something like:

let foo () = test []

This is a standard generic function of type unit -> option<'a>, so this is a perfectly valid construct. You can also use type annotations to specify the type of the result explicitly:

(test []:option<obj>)

Upvotes: 2

Aidan
Aidan

Reputation: 4891

Surely putting the [] case last would do this?

Upvotes: -1

Related Questions