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?
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 typeoption<'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:
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: