为什么Seq.concat的类型涉及灵活类型?

时间:2014-03-31 14:28:30

标签: f# flexible-type

我定义了两个函数,一个有一个,一个没有灵活类型:

let concatA = Seq.concat // ... : seq<#seq<'b>> -> seq<'b>
let concatB = concatA : seq<seq<'b> -> seq<'b>

是否存在我可以使用但不能使用其中一种的上下文?

我的理解是,灵活类型对函数f: #B -> #B很有帮助,其中类型保证(f (x : D)) : D来自D的任何B。我看不出灵活类型对Seq.concat有何帮助?

(我选择Seq.concat作为示例,因为它在documentation for Flexible Types中使用它,但在该示例中使用concatB似乎仍然可以输入所有内容。)

1 个答案:

答案 0 :(得分:4)

它允许您使用一系列特定集合调用Seq.concat。例如:

[ [1]; [2] ] |> concatA  // Works
[ [1]; [2] ] |> concatB  // Does not work

参数是list<list<int>>,它只实现接口seq<list<int>>。这意味着第二个调用不起作用(因为参数需要seq<seq<int>>),但第一个调用的确属于灵活类型 - seq<#seq<int>>seq<list<int>>统一。

有点令人困惑的是,如果F#知道所需的集合文字类型,它有时会在幕后插入转换,因此以下实际上也会起作用(但只是由于隐藏的转换):

concatB [ [1]; [2] ]