如果我有一个定义为
的函数let test = function
| [] -> None
| head::tail -> Some(head)
fsi将允许我定义它,编译将编译它;但如果我真的尝试做test []
,它就会失败。
现在我知道了这个推理,当我给它一个空集时,它无法推断出类型,因此泛型函数失败了,但它能不能做一些更聪明的事情吗? (沿着这句话,“我不知道'a
的类型,但在这种情况下,我没有使用'a
所以我将允许这样做。”)
无论如何,有什么方法可以避免这个问题吗?
答案 0 :(得分:2)
MSDN上有一个很棒的article about value restriction,而Brian有additional notes about tricky aspects,详细解释了这个问题。
当您编写test []
时,结果的类型为option<'a>
,因此编译器需要知道要使用的类型来代替'a
。您实际上并未使用类型'a
的值,但编译器需要编译使用它的代码。 F#不允许使用通用值(通常),因此值需要具体类型。
你可以这样写:
let foo () = test []
这是unit -> option<'a>
类型的标准通用函数,因此这是一个完全有效的构造。您还可以使用类型注释明确指定结果的类型:
(test []:option<obj>)
答案 1 :(得分:-1)
肯定把[]的情况放在最后会这样做吗?