F#中的类型推断问题

时间:2014-09-04 04:28:28

标签: types f# inference

在Visual Studio中使用F#,我发现自己必须更多地明确注释类型,我想要或者应该这样做。我知道一些解决这个问题的技术,特别是使用优秀的前向管道操作员。但是,在许多情况下我无法避免这样做,其中一些似乎是完全错误的。

例如,我有F#代码,如下面的代码段:

    let b = new pqBoard(this)
    let b2,steps = b.Solve()
    if b2.Solved() then 
        let cont = steps |> List.exists (fun (s : string) -> s.IndexOf("Contradiction") >= 0 )

第三行生成一条错误消息,建议在上一行调用Solve方法返回的第一对中需要类型注释。但是该对的第二个元素(字符串列表)很好,并且不需要这样的注释。怎么样的类型检查器似乎可以确定第二个类型中的第二个类型,而不是从单个调用返回的第一个类型?

如下更改第二行可解决问题:

let (b2 : pqBoard,steps) = b.Solve()

为什么我必须明确键入第一个元素而不是第二个元素?

此外,在这种情况下和其他许多情况下,VS在工具提示中正确显示推断类型。我认为VS编辑器在某种意义上是“猜测”,但我还没有看到它猜错了!

我发现必须明确提供类型而不知道为什么需要这些类型令人沮丧和失望。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

如果没有看到pqBoardSolve成员的定义,很难确定究竟发生了什么,但b2steps之间的关键区别您的示例中的steps使用的方式,而不是它们的生成方式。

如果是List.exists,则会将list<'a>传递给'astring必须使用steps,并且明确注释函数参数取list<string>,因此类型检查器可以立即看到b2必须是Solved类型。

对于b2,正在调用成员函数。可能存在许多具有名为.的成员函数的类型,并且F#没有任何方法可以在不知道.的类型的情况下解析调用哪些类型。< / p>

一般情况下 - 尽管它不是通用的 - 在F#中使用{{1}}通常需要在{{1}}左侧明确指定事物的类型而使用更多&#34;功能&#34;结构和类型赢了