首页 文章

F#如何帮助打字推断?

提问于
浏览
8

在Don Syme,Adam Granicz和Antonio Cisternino撰写的Expert F# 2.0中 . 44

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

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

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

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

编辑

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

1 回答

  • 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#类型检查器 . 如果存在类型错误,则上面链接中的摘要提供了一个很好的修复准则:

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

相关问题