Reputation: 4433
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
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