Type inference

https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/conciseness-type-inference.html

类型推断

正如你已经看到的,F#使用了一种叫做 "类型推理 "的技术,大大减少了正常代码中需要明确指定的类型注释的数量。而且,即使需要指定类型,与C#相比,其语法也不那么冗长了。

为了看到这一点,这里有一些C#方法,它们包裹着两个标准的LINQ函数。实现是微不足道的,但方法的签名却极其复杂:

public IEnumerable<TSource> Where<TSource>(
    IEnumerable<TSource> source,
    Func<TSource, bool> predicate
    )
{
    //use the standard LINQ implementation
    return source.Where(predicate);
}

public IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
    IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
    )
{
    //use the standard LINQ implementation
    return source.GroupBy(keySelector);
}

这里是 F# 等含义代码,展示出根本不需要类型注释!

let Where source predicate = 
    //use the standard F# implementation
    Seq.filter predicate source

let GroupBy source keySelector = 
    //use the standard F# implementation
    Seq.groupBy keySelector source

您可能会注意到,“filter”和“groupBy”的标准 F# 实现的参数顺序与 C# 中使用的 LINQ 实现完全相反。 “source”参数放在最后,而不是第一个。这是有原因的,这将在函数式思考系列中解释。

类型推断算法非常擅长从许多来源收集信息以确定类型。在下面的示例中,它正确地推断出列表值是一个字符串列表

let i  = 1
let s = "hello"
let tuple  = s,i      // pack into tuple   
let s2,i2  = tuple    // unpack
let list = [s2]       // type is string list

在这个例子中,它正确地推断出 sumLengths 函数接受一个字符串列表并返回一个 int。

let sumLengths strList = 
    strList |> List.map String.length |> List.sum

// function type is: string list -> int

Last updated