Monday, March 15, 2010

Yielding Lists in F#

I've been watching a great video tutorial on F# ().

One of the things that really interested me was how how easy it is to compose lists. Take the function below that can generate a list of files from a directory and any subsequent subdirectories:

open System.IO

let rec allFiles dir =
[for file in System.IO.Directory.GetFiles dir do
yield file

for subDir in System.IO.Directory.GetDirectories dir do
yield! allFiles subDir]

I'm essentially looping through every file and yielding it into the list. F# intrinsically knows to throw the data into a list because of the brackets. I don't have to worry about creating "objects" to store the data--I treat the data as a function. Also notice the "yield!" statement. The exclamation point tells F# that you want to yield the results of another list into the list. In this case, because I marked the function as recursive("rec"), I can simply recursively call each branch of the file directories until I reach the leaf node.

Here is what this function would look like in C#:

public static List getAllFiles(string dir)
{
var allFiles = new List();

foreach(var file in Directory.GetFiles(dir))
{
allFiles.Add(file);
}

foreach (var subDir in Directory.GetDirectories(dir))
{
getAllFiles(subDir).ForEach(file => allFiles.Add(file));
}

return allFiles;
}

As you can see, F# is much more compact and fluent in expressing functions.

No comments:

Post a Comment