Don Syme,Adam Granicz和Antonio Cisternino的Expert F# 2.0,pg。 44
类型推断:使用|>运算符允许输入类型信息 将对象输入到操纵这些对象的函数。 F#使用 从类型推断收集的信息以解决某些语言 构造,如属性访问和方法重载。这个 依赖于通过文本从左到右传播的信息 一个程序。特别是,在位置右侧键入信息 在解决属性访问和重载时不考虑。
如此清楚地使用|>可以帮助键入推断。
与往常一样,声明类型也很有帮助。
是否有任何其他手段/策略可用于帮助F#类型推断?
修改
正如RamonSnir正确指出的那样,应该让类型推断做尽可能多的工作。因此,添加类型声明只是因为你可以不应该做什么。不要把这个问题或答案视为应该做的事情。我问这个问题是为了帮助更好地理解类型推断的细微差别,以及在类型推断需要帮助的情况下可能有什么帮助。因此,如果类型推断可以在没有帮助的情况下解决所有类型,那么不要给它任何,但是当它确实时,知道一些方法来帮助它会很好。
答案 0 :(得分: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
2)首选方法没有重载。例如,QuickLinq Helpers定义非重载成员以避免LINQ扩展方法中的一堆类型注释。
3)利用任何可用信息为类型检查器提供一些提示。
let makeStreamReader x = new System.IO.StreamReader(x) // fails
let makeStreamReader x = new System.IO.StreamReader(path=x) // works
最后一个例子来自关于F# type inference的精彩文章。
总而言之,您通常不需要帮助F#类型检查器。如果出现类型错误,上面链接中的摘要提供了一个很好的修复准则:
总而言之,如果编译器是你可以做的事情 抱怨缺少类型或信息不足,是:
- 在使用之前定义内容(这包括确保文件按正确的顺序编译)
- 把具有"已知类型的东西"早于具有"未知类型"的东西。特别是,您可以重新排序管道 和类似的链式函数,以便首先输入类型的对象。
- 根据需要进行注释。一个常见的技巧是添加注释直到一切正常,然后一个接一个地拿走它们直到你有 最低需要。尽可能避免注释。不只 它不美观,但它使代码更脆弱。 如果没有明确的话,更改类型要容易得多 对它们的依赖。