F#如何帮助打字推断?

Guy*_*der 8 f# type-inference

在Don Syme,Adam Granicz和Antonio Cisternino的专家F#2.0中,pg.44

类型推断:使用|>运算符可以输入从输入对象到操作这些对象的函数的信息流.F#使用从类型推断收集的信息来解析某些语言结构,例如属性访问和方法重载.这依赖于通过程序文本从左到右传播的信息.特别是,在解决属性访问和过载时,不考虑位置右侧的类型信息.

所以显然使用|>可以帮助进行类型推断.

与往常一样,声明类型也很有帮助.

是否有其他手段/策略可用于帮助F#类型推断?

编辑

正如RamonSnir正确指出的那样,应该让类型推断做尽可能多的工作.因此,添加类型声明只是因为你可以不应该做什么.不要把这个问题或答案视为应该做的事情.我问这个问题是为了帮助更好地理解类型推断的细微差别,以及在类型推断需要帮助的情况下可能有什么帮助.因此,如果类型推断可以在没有帮助的情况下解析所有类型,那么不要给它任何,但是当它确实时,知道一些方法来帮助它会很好.

pad*_*pad 13

几点:

1)首选模块功能属性和方法.

List.map (fun x -> x.Length) ["hello"; "world"] // fails
List.map String.length ["hello"; "world"] // works

let mapFirst xss = Array.map (fun xs -> xs.[0]) xss // fails
let mapFirst xss = Array.map (fun xs -> Array.get xs 0) xss // works
Run Code Online (Sandbox Code Playgroud)

2)首选方法没有重载.例如,QuickLinq Helpers定义非重载成员以避免LINQ扩展方法中的一堆类型注释.

3)利用任何可用信息为类型检查器提供一些提示.

let makeStreamReader x = new System.IO.StreamReader(x) // fails
let makeStreamReader x = new System.IO.StreamReader(path=x) // works
Run Code Online (Sandbox Code Playgroud)

最后一个例子来自关于F#类型推断的优秀文章.

总而言之,您通常不需要帮助F#类型检查器.如果存在类型错误,则上面链接中的摘要提供了一个很好的修复准则:

总而言之,如果编译器抱怨缺少类型或信息不足,那么你可以做的事情是:

  • 在使用它们之前定义它们(这包括确保以正确的顺序编译文件)
  • 把具有"已知类型"的东西放在比具有"未知类型"的东西更早的东西上.特别是,您可以重新排序管道和类似的链接函数,以便首先输入类型化的对象.
  • 根据需要进行注释.一个常见的技巧是添加注释直到一切正常,然后逐个将它们带走,直到你有所需的最小值.尽可能避免注释.它不仅不美观,而且使代码更脆弱.如果没有明确的依赖关系,那么更改类型要容易得多.