As a prior post explained, C#'s type system still lacks some of the flexible constraint refinement available in more powerful functional type systems, but in general C# is powerful enough to encode most interesting functional abstractions.
And I started a new project to demonstrate this: FP#. It provides a number of widely used functional abstractions, like the option type, a lazy type, lists, lazy lists, etc. and map, filter, and fold over all the collection types, including the standard .NET collections API. Each of these abstractions will be available as a separate DLL, so instead of linking to a large library, you can just pick those abstractions you're interested in using.
Besides more flexible typing as in GADTs, expressiveness is the only advantage functional languages still have over C#. Compare the verbosity of the C# option type:
//T is the type variable public abstract class Option<T> { } public sealed class None<T> : Option<T> { } public sealed class Some<T> : Option<T> { T value; public Some(T v) { value = v; } public T Value { get { return value; } } }as compared to an O'Caml definition:
type 'a option = None | Some of 'a (* 'a is the type variable *)This contrast highlights my previous argument in favour of expressiveness; just think of it as 1 line of O'Caml generating 12 lines of C#, since the efficiency of both definitions is equivalent.
To demonstrate the power of existential packages and universal types in C#, I'll be including a number of statically typed abstractions that have only been found in O'Caml and Haskell to date; types like statically sized lists and arrays, number-parameterized types, and other type wizardry resulting in strong partial correctness properties (see: Lightweight Static Capabilities).
It will be particularly interesting to compare the efficiency of a sized type, like a list, to its unsized counterpart, because .NET does not erase types like Java and O'Caml do.