首页 > 代码库 > 6.8.2 列表的绑定操作
6.8.2 列表的绑定操作
6.8.2 列表的绑定操作
我们只讨论了选项值的绑定(bind)操作,实际上,它是非常重要的函数式操作,我们将在第十二章介绍。清单 6.26 显示了对选项值绑定操作的类型签名,以及如果我们定义列表的绑定操作,它的类型签名。
清单 6.26 绑定操作的签名 (F#)
Option.bind : (‘a -> ‘b option) -> ‘aoption -> ‘b option
List.bind : (‘a -> ‘b list) -> ‘alist -> ‘b list
在 F# 库中有List.bind 函数,但名字不同,因此,我们尝试从类型签名弄清楚它能做什么。输入是列表,处理列表中的每个元素,可能得到其他类型值的列表;这个类型的列表也是个绑定操作的返回结果。
实际上,这就表示,操作对每个元素调用给定的函数,将从函数返回的列表连接起来;在F# 库中,这个函数称为 List.collect;在 LINQ 中也有类似的操作,对于特殊类型的查询非常重要。我们将在第十二章详细讨论。
我们可以使用 List.collect 函数,从给定的目录列表中得到所有文件的列表;注意,一个目录通常包含一个文件列表。清单 6.27 显示了我们如何列出这一章所有的源代码文件。
清单 6.27 使用集合列出文件 (F# Interactive)
> open System.IO;;
> let directories =
[ "C:\Source\Chapter06\Chapter06_CSharp";
"C:\Source\Chapter06\Chapter06_FSharp";
"C:\Source\Chapter06\FunctionalCSharp" ];;
val directories : string list
> directories |> List.collect (fun d–>
d |> Directory.GetFiles | 得到给定目录的文件名列表
|> List.ofSeq |
|> List.map Path.GetFileName );; |
val it : string list =
["Chapter06_CSharp.csproj"; "Program.cs";"Chapter06_FSharp.fsproj";
"Script.fsx"; "FunctionalCSharp.csproj";"List.cs";
"Option.cs"; "Tuple.cs" ]
集合(collect)操作对输入列表中的每个目录调用给定的 lambda 函数;然后,lambda 函数获得目录中的所有文件,把它们从数组转换成列表,再使用 List.map,从完整路径得到文件名;然后,结果会收集到一个列表中,作为整体的结果返回。当你听到在 .NET 3.5 中也有这个操作,可能不会感到诧异,它表示为 SelectMany 方法;在 C# 3.0 的查询表达式中,指定多个 from 子句,就要使用这个方法。
6.8.2 列表的绑定操作