Подтвердить что ты не робот

Как прочитать файл в seq строк в F #

Это версия С#:

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();
    }
  }
}

Но для прямого перевода необходима изменяемая переменная.

4b9b3361

Ответ 1

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

Ответ 2

Если вы используете .NET 4.0, вы можете просто использовать File.ReadLines.

> let readLines filePath = System.IO.File.ReadLines(filePath);;

val readLines : string -> seq<string>

Ответ 3

Чтобы ответить на вопрос, есть ли библиотечная функция для инкапсуляции этого шаблона - для этого нет функции, но есть функция, которая позволяет вам генерировать последовательность из некоторого состояния, называемого Seq.unfold. Вы можете использовать его для реализации вышеперечисленных функций:

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

Значение sr представляет считыватель потока и передается как состояние. Пока он дает вам ненулевые значения, вы можете вернуть Some содержащий элемент для генерации и состояние (которое может измениться, если вы захотите). Когда он читает null, мы удаляем его и возвращаем None, чтобы закончить последовательность. Это не является прямым эквивалентом, потому что он не имеет права распоряжаться StreamReader, когда генерируется исключение.

В этом случае я бы определенно использовал выражение последовательности (которое более элегантно и читаемо в большинстве случаев), но полезно знать, что он также может быть написан с использованием функции более высокого порядка.

Ответ 4

    let lines = File.ReadLines(path)                

    // To check
    lines |> Seq.iter(fun x -> printfn  "%s" x) 

Ответ 5

В .NET 2/3 вы можете:

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

и на .NET 4:

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

Ответ 6

Чтобы избежать "System.ObjectDisposedException: не удается прочитать из закрытого TextReader". исключение, используйте:

let lines = seq { yield! System.IO.File.ReadLines "/path/to/file.txt" }