任何避免这种类型推断问题的方法?

问题描述:

如果我有一个函数定义为任何避免这种类型推断问题的方法?

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

FSI可以让我定义这个编译就编译它;但如果我真的试图做test [],它会崩溃。

现在我知道推理,当我给它一个空集,它不能推断类型,所以通用函数失败,但它可以做一些有点聪明吗? (沿着“我不知道'a的类型,但在这种情况下,我不使用'a,所以我打算允许这样做”)。这个问题?

有一个伟大的article about value restriction MSDN和additional notes about tricky aspects布赖恩,详细解释这个问题。

当您编写test []时,结果的类型为option<'a>,因此编译器需要知道要使用的类型来代替'a。您实际上并未使用类型'a的值,但编译器需要编译使用它的代码。 F#不允许使用通用值(一般),因此该值需要具体的类型。

您可以编写类似:

let foo() = test [] 

这是unit -> option<'a>类型的标准通用功能,所以这是一个完全有效的结构。您还可以使用类型批注指定结果明确的类型:

(test []:option<obj>) 
+0

很好的类型,你可以写让foo()= test [] - 但当你试图执行它时,foo仍然会出错...那里的乐趣在哪里?标记为答案因为指定obj看起来像是唯一的方法。 – Massif 2011-06-07 14:01:32

+2

@Massif - 问题是,你想如何使用结果,输入列表从哪里来?在任何实际的例子中,你都会在一些指定类型的上下文中使用代码。 (Brian的文章中的部分函数应用程序示例并非如此,但是您的代码可能会出现在更广泛的上下文中。) – 2011-06-07 14:04:27

+0

这很可能是真的 – Massif 2011-06-07 14:06:22

确实把[]情况最后会做到这一点?

+0

为什么会作出任何区别,我还没有告诉它“一个...... – Massif 2011-06-07 13:59:18