如何将文件读入F#中的一行内容

这是C#版本:

public static IEnumerable<string> ReadLinesEnumerable(string path) { using ( var reader = new StreamReader(path) ) { var line = reader.ReadLine(); while ( line != null ) { yield return line; line = reader.ReadLine(); } } } 

但直接翻译需要一个可变的variables。

 let readLines (filePath:string) = seq { use sr = new StreamReader (filePath) while not sr.EndOfStream do yield sr.ReadLine () } 

如果您使用.NET 4.0,则可以使用File.ReadLines 。

 > let readLines filePath = System.IO.File.ReadLines(filePath);; val readLines : string -> seq<string> 

要回答是否有封装这个模式的库函数的问题 – 没有一个函数完全是这样的,但是有一个函数允许你从一个称为Seq.unfold状态产生序列。 你可以用它来实现上面的function:

 new StreamReader(filePath) |> Seq.unfold (fun sr -> match sr.ReadLine() with | null -> sr.Dispose(); None | str -> Some(str, sr)) 

sr值表示stream读取器,并作为状态传递。 只要它给你非空值,你可以返回Some包含一个要生成的元素和状态(如果你想要的话可​​以改变)。 当它读取null ,我们将它处置并返回None来结束序列。 这不是一个直接的等价物,因为当引发exception时,它不能正确处理StreamReader

在这种情况下,我肯定会使用序列expression式(在大多数情况下它更优雅,更易读),但是知道它也可以使用更高级的函数编写是有用的。

  let lines = File.ReadLines(path) // To check lines |> Seq.iter(fun x -> printfn "%s" x) 

在.NET 2/3上,你可以这样做:

 let readLines filePath = File.ReadAllLines(filePath) |> Seq.cast<string> 

和.NET 4上:

 let readLines filePath = File.ReadLines(filePath);;