ApacheTech.Common.FunctionalCSharp 1.1.0

dotnet add package ApacheTech.Common.FunctionalCSharp --version 1.1.0
                    
NuGet\Install-Package ApacheTech.Common.FunctionalCSharp -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ApacheTech.Common.FunctionalCSharp" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ApacheTech.Common.FunctionalCSharp" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="ApacheTech.Common.FunctionalCSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ApacheTech.Common.FunctionalCSharp --version 1.1.0
                    
#r "nuget: ApacheTech.Common.FunctionalCSharp, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ApacheTech.Common.FunctionalCSharp@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ApacheTech.Common.FunctionalCSharp&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=ApacheTech.Common.FunctionalCSharp&version=1.1.0
                    
Install as a Cake Tool

Functional C# - End-Game LINQ Library

A comprehensive C# library that brings practical functional programming tools to everyday .NET development. It provides monads, discriminated unions, memoisation helpers, currying and partial application utilities, and a small set of LINQ-style extensions to make common functional patterns concise and expressive.

Support the Author

If you find this library useful and would like to support its continued development, please consider one of the options below. Your support helps fund maintenance, documentation and new features.


Installation

Install the package from NuGet:

dotnet add package ApacheTech.Common.FunctionalCSharp

Alternatively, add the ApacheTech.Common.FunctionalCSharp project to your solution and reference it directly during development.


Key Concepts

This section summarises the principal APIs and how they are intended to be used.

Monads

Monads in this library are pragmatic tools for modelling optional values and fallible computations.

  • Maybe<T> represents an optional value. Use Actual<T> for present values and Nothing<T> for absence. Companion extensions such as ToMaybe() and Bind() make chaining straightforward and safe.

  • Identity<T> is a minimal wrapper that carries a value and supports implicit conversions. It is useful when a monadic interface is desired without special semantics for missing values.

  • Attempt<T> models computations that may fail. Success<T> contains the result; Fail<T> contains an exception and short-circuits subsequent operations.

Usage guidance: prefer Maybe where absence is a valid state and Attempt where exceptions should be modelled explicitly in the computation chain.

OneOf � discriminated unions

OneOf<T1, T2> holds one of two possible types. Use Match or Invoke to handle each case explicitly. This pattern is useful when a function may return one of a small set of distinct types (for example, a result or an error value) and you want callers to handle both cases explicitly.

Memento (memoisation)

Memento<TInput, TOutput> decorates a pure function with a dictionary-backed cache. It offers implicit conversions to and from Func<TInput, TOutput> to ease substitution of decorated and plain functions.

Important caveats: use only for pure, deterministic functions, and ensure TInput is a suitable dictionary key (immutable or with stable equality semantics).

Functional helpers (Apply & Curry)
  • Apply (partial application) binds leading arguments of a function to produce a function of smaller arity, which can be useful for creating specialised functions.
  • Curry converts a multi-argument function into nested single-argument functions, facilitating composition and reuse in functional pipelines.

Both families include overloads for a broad range of arities.

Monadic LINQ-style helpers
  • Map applies a transformation to a value and returns the result.
  • Alt attempts a primary mapping and uses a fallback when the primary result is a default value.
  • Fork executes multiple independent paths against the same input and combines the results using a provided join function.
  • TryValidate returns whether all predicates hold and provides the set of failing rules; Validate simply returns a boolean.

These helpers aim to make common patterns succinct and readable.

Try/catch helpers & object utilities

A small set of helpers reduces boilerplate around common error handling patterns. TryCatch<TException> wraps an Action with a handler for the specified exception type; convenience variants include TryOrFailFast, TryOrThrow, TryOrLogToConsole and TryOrLogToDebug.

IsDefaultValue<T> tests whether a value equals the default for its type and is useful for concise default checks.


Examples / Recipes

This section contains compact examples illustrating typical usage patterns.

Chaining fallible computations

Parse, transform and format only when each step succeeds. The chain short-circuits on failure.

using ApacheTech.Common.FunctionalCSharp.Monads;
using ApacheTech.Common.FunctionalCSharp.Monads.Extensions;

var formatted = "123"
    .ToMaybe()
    .Bind(i => (i * 2).ToMaybe())
    .Map(i => i.ToString());
Handling multiple result types with OneOf

Use OneOf to return one of two types and handle both cases explicitly.

var result = new OneOf<int, string>(404);
string message = result.Match(
    code => $"Error code: {code}",
    text => $"Message: {text}"
);
Memoising an expensive pure function

Decorate a pure function with Memento to cache results for repeated inputs.

Func<string, string> computeKey = s => s.ToUpperInvariant(); // expensive
var memoKey = new Memento<string, string>(computeKey);
var k1 = memoKey.Invoke("abc"); // computed
var k2 = memoKey.Invoke("abc"); // cached
Validation helpers

Run multiple predicates and inspect failures.

var user = new User { Name = "", Age = 12 };
var ok = user.TryValidate(out var failed,
    u => !string.IsNullOrWhiteSpace(u.Name),
    u => u.Age >= 13);

if (!ok)
{
    foreach (var rule in failed) Console.WriteLine("Validation failed");
}

Contributing

Contributions, bug reports and improvements are welcome. Please open issues or pull requests against the GitHub repository. When contributing, please follow the existing code style and add unit tests for new behaviours.

  • Run dotnet test in the test project before submitting changes.

Licence

This project is released under the terms of the licence included in LICENCE.md.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ApacheTech.Common.FunctionalCSharp:

Package Downloads
VintageStory.Gantry

Gantry MDK is a Mod Developent Kit, used to create third-party plugins for the game Vintage Story, by Anego Studios.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 92 9/14/2025
1.0.0 2,136 11/15/2022

ApacheTech.Common.FunctionalCSharp v1.1.0

Build: Updated to .NET 8.0 SDK.