代码之家  ›  专栏  ›  技术社区  ›  J Cooper

为什么F的类型推断如此易变?

  •  66
  • J Cooper  · 技术社区  · 14 年前

    F编译器似乎以(相当)严格的从上到下、从左到右的方式执行类型推断。这意味着您必须做一些事情,比如在使用之前放置所有定义,文件编译的顺序很重要,并且您往往需要重新排列数据(通过 |> 或者你有什么)避免有明确的类型注释。

    要使其更具灵活性有多困难?这是否计划用于未来版本的f_?显然可以这样做,因为haskell(例如)在同样强大的推理中没有这样的限制。导致这一现象的是F的设计或思想有什么本质上的不同吗?

    5 回复  |  直到 8 年前
        1
  •  51
  •   Brian    14 年前

    关于“哈斯克尔同样有力的推论”,我认为哈斯克尔不必处理

    • OO风格的动态子类型(类型类可以做一些类似的事情,但是类型类更容易输入/推断)
    • 方法重载(类型类可以做一些类似的事情,但类型类更容易键入/推断)

    也就是说,我认为F必须处理一些哈斯克尔没有处理的困难的事情。(几乎可以肯定的是,哈斯克尔必须处理一些F没有处理过的困难问题。)

    正如其他答案所提到的,大多数主要的.NET语言都将Visual Studio工具作为主要的语言设计影响(请参见Linq是如何“从……开始”的)。选择“而不是SQL-Y”选择…从“,通过从程序前缀获取IntelliSense来激励)。智能感知、错误波形和错误消息可理解性都是影响F设计的工具因素。

    很可能做得更好,推断得更多(不牺牲其他经验),但我不认为这是我们未来版本语言的优先考虑事项。(哈斯凯勒人可能认为F型推理有点弱,但他们可能被认为F型推理很强的C型推理所压倒。:)

    以不间断的方式扩展类型推断可能也很困难;在未来的版本中,将非法程序更改为合法程序是可以的,但是您必须非常小心,以确保以前的合法程序不会在新的推理规则下更改语义,并且名称解析(每种语言都是一个可怕的梦魇)可能会相互作用。类型推理以令人惊讶的方式发生了变化。

        2
  •  53
  •   J D    14 年前

    导致这一现象的是F的设计或思想有什么本质上的不同吗?

    对。F使用的是象征性的而不是结构性的打字,因为它更简单,因此也更容易被普通人使用。

    请考虑以下F示例:

    let lengths (xss: _ [] []) = Array.map (fun xs -> xs.Length) xss
    
    let lengths (xss: _ [] []) = xss |> Array.map (fun xs -> xs.Length)
    

    前者不编译,因为 xs 无法推断匿名函数内部,因为f无法用 Length 成员“。

    相反,OCAML可以表达直接等效物:

    let lengths xss = Array.map (fun xs -> xs#length) xss
    

    因为ocaml可以表示该类型(它是 <length: 'a ..> )请注意,这需要比f或haskell当前所具有的更强大的类型推断,例如,ocaml可以推断和类型。

    然而,这个特性是一个可用性问题。例如,如果代码中的其他地方出错,那么编译器还没有推断出 XS 它应该是一个数组,因此它所能提供的任何错误消息只能提供类似于“某个具有长度成员的类型”而不是“数组”的信息。只有稍微复杂一些的代码,这就很快失控了,因为你有大量的类型,很多结构推断的成员不完全统一,导致不可理解的(C++/STL类)错误消息。

        3
  •  19
  •   holsee    8 年前

    我认为f使用的算法的好处是,它很容易(至少大致)解释它的工作原理,因此一旦你理解了它,你就可以对结果有一些期望。

    算法总是有一些局限性。目前,很容易理解。对于更复杂的算法,这可能很困难。例如,我认为你可能会遇到这样的情况,即你认为算法应该能够推断出某些东西——但是如果它足够通用,能够覆盖整个案例,那么它将是不可判定的(例如,可以永远保持循环)。

    另一个想法是,从上到下检查代码与我们读取代码的方式相对应(至少有时如此)。所以, 也许吧 事实上,我们倾向于以一种能够进行类型推断的方式编写代码,这也使得代码对人们更具可读性…

        4
  •  17
  •   Robert Harvey Isaac Blanco    14 年前

    f使用一次编译,这样 只能引用类型或 已定义的函数 在文件的前面 当前在或出现在文件中 在前面的 编译顺序。

    我最近问过唐·赛姆 多个源传递以改进 类型推断过程。他的回答是 “是的,可以进行多通 类型推断。也有 产生一个 有限约束集。

    然而,这些方法往往 错误消息和差 IntelliSense产生视觉效果 编辑。

    http://www.markhneedham.com/blog/2009/05/02/f-stuff-i-get-confused-about/#comment-16153

        5
  •  13
  •   wren romano    14 年前

    简短的回答是,F_基于SML和OCAML的传统,而Haskell来自米兰达、戈弗等稍有不同的世界。历史传统的差异是微妙的,但普遍存在的。这一区别在其他现代语言中也有相似之处,例如具有相同排序限制的ML-like coq与不具有相同排序限制的haskell-like agda。

    这种差异与懒惰与严格的评估有关。宇宙的哈斯克尔一方相信懒惰,一旦你已经相信了懒惰,把懒惰添加到像类型推理这样的事情上的想法就不需要动脑筋了。然而,在宇宙的ML端,每当需要惰性或相互递归时,都必须通过使用关键字明确指出,例如 具有 , , 录制 等等,我更喜欢haskell方法,因为它可以减少样板代码的产生,但是有很多人认为最好把这些事情明确化。