有什么方法可以避免这种类型的推理问题?

时间:2011-06-07 13:30:17

标签: f# type-inference

如果我有一个定义为

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

fsi将允许我定义它,编译将编译它;但如果我真的尝试做test [],它就会失败。

现在我知道了这个推理,当我给它一个空集时,它无法推断出类型,因此泛型函数失败了,但它能不能做一些更聪明的事情吗? (沿着这句话,“我不知道'a的类型,但在这种情况下,我没有使用'a所以我将允许这样做。”)

无论如何,有什么方法可以避免这个问题吗?

2 个答案:

答案 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)

肯定把[]的情况放在最后会这样做吗?

相关问题