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 c开发者_如何转开发ompile 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 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>)
Surely putting the [] case last would do this?
精彩评论