任何避免这种类型推断问题的方法?
问题描述:
如果我有一个函数定义为任何避免这种类型推断问题的方法?
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>)
很好的类型,你可以写让foo()= test [] - 但当你试图执行它时,foo仍然会出错...那里的乐趣在哪里?标记为答案因为指定obj看起来像是唯一的方法。 – Massif 2011-06-07 14:01:32
@Massif - 问题是,你想如何使用结果,输入列表从哪里来?在任何实际的例子中,你都会在一些指定类型的上下文中使用代码。 (Brian的文章中的部分函数应用程序示例并非如此,但是您的代码可能会出现在更广泛的上下文中。) – 2011-06-07 14:04:27
这很可能是真的 – Massif 2011-06-07 14:06:22