Function Composition in C# 3.0

K

KeeganDunn

I've been leaning pretty heavily on the new C# 3.0 features while
simultaneously playing around with Haskell and other FP-oriented
languages. One problem that comes up often is the lack of a function
composition syntax.

For instance, there's this bit of code in one of my projects:

/* Convert all doc files in the directory
to plain text, strip out extraneous formatting,
and run them through the summary parser */
var results = filenames.ConvertAll
(file => parseSummary(cleanTxt(docToTxt(file))))

It's not awful. It's just not ideal. In haskell I would just use the
dot notation:

map (parseSummary . cleanTxt . docToTxt) filenames

It's more readable and there's less parenthesis overload.

An alternative is to have a larger list of ConvertAll statements.
Assuming there's no compiler magic happening, this seems like a much
slower approach, although it is more readable than my first example.

var results = filenames
.ConvertAll(docToTxt)
.ConvertAll(cleanTxt)
.ConvertAll(parseSummary)

I'm sure other people trying to adopt a more functional style in C#
3.0 have come up against this. Has a popular pattern emerged for
dealing with this?

Cheers,
kd
 
N

Nicholas Paldino [.NET/C# MVP]

kd,

This is the whole point of Extension Methods. You can define a static
class with static methods using the "this" keyword for the first parameter
to define methods that you can call on the type of that parameter.

So, depending on the type of the file (let's say it is MyFile) you could
do:

namespace MyNamespace
{
public static class MyFileExtensions
{
public static string docToTxt(this MyFile file)
{
// Do stuff.
}
}
}

Now, when you have a reference to this class (or it is in the same
project) and you have the namespace the class belongs in a using statement
at the top of a code file, you can do this:

// Needed for the extension method if not in that namespace.
using MyNamespace;

// Somewhere in code:
MyFile myFile = ...;

// Call the method.
myFile.docToTxt();

Using this technique (and you can define more than one extension method
on a type), you can end up doing this:

var result = filename.docToTxt().cleanTxt().parseSummary();

Hope this helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top