F# Pipelining in C#

Here is one such example where F# developers try to make it look like F# can do things that C# can not.


F# code
F# code that apparently is much easier to read than C# code:

HttpGet "http://www-static.cc.gatech.edu/classes/cs2360_98_summer/hw1"
|> fun s -> Regex.Replace(s, "[^A-Za-z']", " ")
|> fun s -> Regex.Split(s, " +")
|> Set.of_array
|> Set.filter (fun word -> not (Spellcheck word))
|> Set.iter (fun word -> printfn "   %s" word)

C# code
My attempt to accomplish the same in C#.

    .Transform(s => Regex.Replace(s, "[^A-Za-z']", " "))
    .Transform(s => Regex.Split(s, " +"))
    //.AsParallel()  // [EDIT] now with parallelism support
    .Where(word => !Spellcheck(word))
    .Process(word => Console.WriteLine("  {0}", word))

I think that’s fairly similar?

OK, I cheated, “Transform”,”Process” and “Execute” does not exist out of the box in C#.
You would have to write those extension methods yourself.
However, they are reusable and fits nicely into a util lib.

public static class Extensions
    public static TOut Transform<TIn, TOut>(this TIn self, Func<TIn, TOut> selector)
        return selector(self);

    public static IEnumerable<T> Process<T>(this IEnumerable<T> self, Action<T> action)
        return self.Select(item =>
            return item;

    public static ParallelQuery<T> Process<T>(this ParallelQuery<T> self, Action<T> action)
        return self.Select(item =>
            return item;

    public static void Execute<T>(this IEnumerable<T> self)

    public static void Execute<T>(this ParallelQuery<T> self)

Either way, I hope this shows that you can accomplish the same thing using good old C# instead of F#.


  1. Pattern matching:

    let rec zip la lb =
    match (la, lb) with
    | (ha::ta), (hb::tb) -> (ha, hb) :: (zipWith func ta tb)
    | _ -> []

    Pattern matching on one argument can look nice in C# (not as nice as in F#, IMHO), but on several arguments at once you are going to have a problem.

    The closest I can come up with is (FList is a functional list class):

    FList<Tuple<A>> Zip<A>(FList<A> la, FList<B> lb)
    return la.Match(() => FList<Tuple<A>>.Empty,
    (ha, ta) => lb.Match(() => FList<Tuple<A>>.Empty,
    (hb, tb) => Tuple.New(ha, hb).Cons(Zip(la, lb))));

    which looks _a lot_ worse to me. And this is a very simple pattern match…

    Full type inference.

    I’d add first-class events, but Reactive Framework will be available for all languages, so I won’t.

  2. hi,

    First of all. Thanks very much for your useful post.

    I just came across your blog and wanted to drop you a note telling you how impressed I

    was with the information you have posted here.

    Please let me introduce you some info related to this post and I hope that it is useful

    for .Net community.

    There is a good C# resource site, Have alook



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s