【问题标题】:Why can't F#'s type inference handle this?为什么 F# 的类型推断不能处理这个?
【发布时间】:2009-05-10 05:07:34
【问题描述】:

我有一个 FileInfo 序列,但我只关心它们的字符串名称,所以我想要一个字符串序列。起初我尝试过这样的事情:

Seq.map (fun fi -> fi.Name) fis

但由于某种原因,F# 的类型推断不足以实现这一点,并让我明确地给“fi”一个类型:

Seq.map (fun (fi : FileInfo) -> fi.Name) fis

为什么需要这个注解?如果知道fis : seq<FileInfo>Seq.map : ('a -> 'b) -> seq<'a> -> seq<'b>,那么是不是应该推断lambda表达式的类型是FileInfo -> 'b,然后从fi.Name : string进一步推断它的类型是FileInfo -> string

【问题讨论】:

    标签: f# type-inference


    【解决方案1】:

    类型推断从左到右进行。这是管道操作符有用的地方;如果你已经知道'fis'的类型,那么写成

    fis |> Seq.map (fun fi -> fi.Name)
    

    推理对你有用。

    (一般来说,形式的表达式

    o.Property
    o.Method args
    

    要求知道'o'的类型先验;对于大多数其他表达式,当没有固定类型时,推理系统可以“浮动约束”,稍后可以解决,但对于这些情况,没有“所有类型具有名为 P 的属性”形式的约束或'所有具有名为 M 的方法的类型'(如鸭子类型),可以推迟并在以后解决。所以你现在需要这些信息,否则推理会立即失败。)

    另请参阅overview of type inference in F#

    【讨论】:

    • 我希望他们使类型推断更加健壮。我已经遇到过一些必须对类中的方法重新排序的情况,否则我会遇到过于泛型的类型错误。
    • 对于它的价值,这篇博文及其一些 cmets 对 F# 在其类型检查器中的一些优点和缺点进行了有用的解释:neilmitchell.blogspot.com/2008/12/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多