Skip to content

atifaziz/Partials

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Partials

Build Status NuGet

Partials is a library of partially applied .NET utility and primitive functions that help reduce the need for writing out simple lambdas. It is especially useful when authoring LINQ to Objects queries.

Motivation

Suppose the following example that rounds up 5 double-precision numbers up to their second fractional digit:

var nums = new[]
{
    0.32313,
    0.55369,
    0.95692,
    0.11786,
    0.54233,
};

var result = string.Join(", ", nums.Select(x => Math.Round(x, 2)));
Console.WriteLine(result); // 0.32, 0.55, 0.96, 0.12, 0.54

Using Partials, the Select can be written without a lambda:

var result = string.Join(", ", nums.Select(Float64.Round(2)));

Below is another example where the double-precision floats are parsed from strings and then rounded up:

var nums = new[]
{
    "0.32313",
    "0.55369",
    "0.95692",
    "0.11786",
    "0.54233",
};

var result = string.Join(", ", nums.Select(s => Math.Round(double.Parse(s, CultureInfo.InvariantCulture), 2)));
Console.WriteLine(result); // 0.32, 0.55, 0.96, 0.12, 0.54

Using Partials, the same can be expressed more simply:

var result = string.Join(", ", nums.Select(Float64.Parse())
                                   .Select(Float64.Round(2)));

Partials also gives you Then for composing functions together, which can be used to turn the chained projections, like the two Select operations in the example above, into one:

var result = string.Join(", ", nums.Select(Float64.Parse()
                                                  .Then(Float64.Round(2))));

The next example shows more composition in action, where each string is parsed into a number, multiplied by 5, square-rooted and then capped to 1.5 before being rounded up:

var result = string.Join(",", nums.Select(Float64.Parse()
                                                 .Then(x => x * 5)
                                                 .Then(Float64.Sqrt)
                                                 .Then(Float64.Min(1.5))
                                                 .Then(Float64.Round(2))));

You can also negate any predicate function by statically importing (using static) the FuncModule and using Not:

var strs = new[] { "foo", "bar", "baz", "quux" };

var r1 = string.Join(", ", strs.Where(Str.Contains("a")));
Console.WriteLine(r1);  // bar, baz

var r2 = string.Join(", ", strs.Where(Not(Str.Contains("a"))));
Console.WriteLine(r2);  // foo, quux