Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How read a file into a seq of lines in F#

Tags:

f#

This is C# version:

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

But directly translating needs a mutable variable.

like image 951
Yin Zhu Avatar asked Mar 02 '10 18:03

Yin Zhu


People also ask

How to read specific lines from a file in Python?

Use readlines() to Read the range of line from the File The readlines() method reads all lines from a file and stores it in a list. You can use an index number as a line number to extract a set of lines from it. This is the most straightforward way to read a specific line from a file in Python.

How do I read a text file line by line in Python?

Method 1: Read a File Line by Line using readlines() readlines() is used to read all the lines at a single go and then return them as each line a string element in a list. This function can be used for small files, as it reads the whole file content to the memory, then split it into separate lines.

What is the method to read a single line at a time from the file?

Java Read File line by line using BufferedReaderBufferedReader readLine() method to read file line by line to String. This method returns null when end of file is reached.

When reading a file line by line the exact contents can be printed by?

Reading a File Line-by-Line in Python with readline() This code snippet opens a file object whose reference is stored in fp , then reads in a line one at a time by calling readline() on that file object iteratively in a while loop. It then simply prints the line to the console.


5 Answers

If you're using .NET 4.0, you can just use File.ReadLines.

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

val readLines : string -> seq<string>
like image 99
Joel Mueller Avatar answered Oct 16 '22 04:10

Joel Mueller


open System.IO

let readLines (filePath:string) = seq {
    use sr = new StreamReader (filePath)
    while not sr.EndOfStream do
        yield sr.ReadLine ()
}
like image 24
ChaosPandion Avatar answered Oct 16 '22 05:10

ChaosPandion


To answer the question whether there is a library function for encapsulating this pattern - there isn't a function exactly for this, but there is a function that allows you to generate sequence from some state called Seq.unfold. You can use it to implement the functionality above like this:

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

The sr value represents the stream reader and is passed as the state. As long as it gives you non-null values, you can return Some containing an element to generate and the state (which could change if you wanted). When it reads null, we dispose it and return None to end the sequence. This isn't a direct equivalent, because it doesn't properly dispose StreamReader when an exception is thrown.

In this case, I would definitely use sequence expression (which is more elegant and more readable in most of the cases), but it's useful to know that it could be also written using a higher-order function.

like image 28
Tomas Petricek Avatar answered Oct 16 '22 06:10

Tomas Petricek


    let lines = File.ReadLines(path)                

    // To check
    lines |> Seq.iter(fun x -> printfn  "%s" x) 
like image 24
maria Avatar answered Oct 16 '22 05:10

maria


On .NET 2/3 you can do:

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

and on .NET 4:

let readLines filePath = File.ReadLines(filePath);;
like image 28
Lars Tackmann Avatar answered Oct 16 '22 05:10

Lars Tackmann