简体   繁体   English

F#中的类型推断问题

[英]Type inference problems in F#

Using F# in Visual Studio, I find myself having to explicitly annotate types a lot more that I would like, or should have to. 在Visual Studio中使用F#,我发现自己不得不显式地注释类型,这是我想要的,也应该是必须的。 I am aware of some techniques for resolving this, in particular the use of the excellent forward piping operator. 我知道一些解决此问题的技术,特别是出色的前向管道算子的使用。 However, in many circumstances I am unable to avoid doing so, and some of them seem just plain wrong. 但是,在许多情况下,我无法避免这样做,其中有些似乎是完全错误的。

For example, I have F# code like the following snippet: 例如,我具有以下代码段的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 )

The third line generates an error message suggesting a type annotation is required for the first of the pair returned from the call to the Solve method on the previous line. 第三行生成一条错误消息,提示从上一行对Solve方法的调用返回的一对中的第一对需要类型注释。 But the second element of the pair (a list of strings) is fine, and requires no such annotation. 但是该对中的第二个元素(字符串列表)很好,并且不需要这样的注释。 How is it that the type checker can seemingly be certain of the type of the second of the pair, but not of the first when the are returned from a single call? 当从单个调用返回时,类型检查器看起来如何确定该对中的第二个类型,而不是第一个类型呢?

Changing the second line as follows fixes the problem: 如下更改第二行可解决此问题:

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

Why must I explicitly type the first element and not the second? 为什么我必须显式键入第一个元素而不是第二个?

Furthermore, in this case and many others, inferred types are correctly displayed by VS in the tooltips. 此外,在这种情况下以及其他情况下,VS会在工具提示中正确显示推断的类型。 I assume that the VS editor is "guessing" in some sense, but I have yet to see it guess incorrectly! 我认为VS编辑器在某种意义上是“猜测”,但是我还没有看到它猜对了!

I find it frustrating and disappointing to have to explicitly provide types without any good idea of why they are required. 我发现必须显式地提供类型而对为什么需要它们没有任何好主意,这令人沮丧和失望。 Any help would be appreciated. 任何帮助,将不胜感激。

Without seeing the definition of pqBoard and the Solve member it's hard to be sure exactly what's going on, but the key difference between b2 and steps in your sample is how they are used as opposed to how they are generated. 在没有看到pqBoardSolve成员的定义的pqBoard ,很难确定到底发生了什么,但是样本中b2steps之间的主要区别在于它们的使用方式以及生成方式。

In the case of steps , it's passed into List.exists , which must take list<'a> for some 'a , and the function argument is explicitly annotated to take string , so the type-checker can immediately see that steps must be of type list<string> . 如果是steps ,则将其传递到List.exists ,该list<'a>必须对某些'a使用list<'a> ,并且显式注释了函数参数以采用string ,因此类型检查器可以立即看到steps必须为键入list<string>

For b2 , a member function is being called. 对于b2 ,正在调用成员函数。 There could be a lot of types with a member function named Solved , and F# doesn't have any way to resolve which of those types is being called without somehow knowing the type of b2 . 带有名为Solved的成员函数的类型可能很多,而F#没有某种方式不知道b2的类型就无法解决调用这些类型中的哪一种。

In general - though it's not universal - using . 总的来说-尽管不是通用的-使用. in F# will often require the type of the thing on the left-hand side of the . 在F#中,通常需要在左侧添加事物的类型. to be explicitly specified somewhere earlier, whereas using the more "functional" constructs and types won't. 在更早的地方明确指定,而不会使用功能更多的结构和类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM