ARPL 1.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package ARPL --version 1.0.3
                    
NuGet\Install-Package ARPL -Version 1.0.3
                    
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="ARPL" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ARPL" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="ARPL" />
                    
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 ARPL --version 1.0.3
                    
#r "nuget: ARPL, 1.0.3"
                    
#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 ARPL@1.0.3
                    
#: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=ARPL&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=ARPL&version=1.0.3
                    
Install as a Cake Tool

ARPL (Advanced Result Pattern Library)

A lightweight C# library providing robust discriminated unions for error handling and functional programming patterns. ARPL offers two main types: Either<L,R> for generic discriminated unions and SResult<R> for specialized success/error handling.

Features 🚀

  • Either<L,R> - A generic discriminated union that can hold one of two possible types
  • SResult<R> - A specialized result type for handling success/error scenarios
  • Implicit conversions between Either<Error,R> and SResult<R>
  • Pattern matching support for elegant value handling
  • Type-safe error handling without exceptions
  • Functional programming friendly design

Type Features

Either<L,R>

  • Left(L value) - Creates a new Either instance containing a left value
  • Right(R value) - Creates a new Either instance containing a right value
  • IsLeft - Indicates if the instance contains a left value
  • IsRight - Indicates if the instance contains a right value
  • Match - Pattern matching for transforming or handling the contained value
  • MatchAsync - Asynchronous pattern matching for handling the contained value
  • Map - Transforms the right value using a mapping function (if present)
  • MapAsync - Transforms the right value using an async mapping function (if present)

SResult<R>

  • Success(R value) - Creates a new success result
  • Error(Error value) - Creates a new error result
  • IsSuccess - Indicates if the result represents success
  • IsFail - Indicates if the result represents an error
  • SuccessValue - Gets the success value
  • ErrorValue - Gets the error value
  • Match - Pattern matching for transforming or handling the result
  • MatchAsync - Asynchronous pattern matching for handling the result
  • Map - Transforms the success value using a mapping function (if present)
  • MapAsync - Transforms the success value using an async mapping function (if present)

Getting Started 🏃

Installation

Install via NuGet:

Install-Package ARPL

Basic Usage

Using Either<L,R>
using Arpl.Core;

// Create Either instances
Either<string, int> leftValue = Either<string, int>.Left("error message");
Either<string, int> rightValue = Either<string, int>.Right(42);

// Pattern match to handle both cases
leftValue.Match(
    left => Console.WriteLine($"Left value: {left}"),
    right => Console.WriteLine($"Right value: {right}"));

// Asynchronous pattern matching
await rightValue.MatchAsync(
    async left => { await Task.Delay(10); Console.WriteLine($"Left async: {left}"); return 0; },
    async right => { await Task.Delay(10); Console.WriteLine($"Right async: {right}"); return right; }
);

// Mapping right value
Either<string, string> mapped = rightValue.Map(val => $"Number: {val}");

// Async mapping
Either<string, string> asyncMapped = await rightValue.MapAsync(async val => {
    await Task.Delay(10);
    return $"Number: {val}";
});
Using SResult<R>
// Create success result
SResult<int> success = SResult<int>.Success(42);

// Create error result
SResult<int> error = SResult<int>.Error(new Error("Something went wrong"));

// Pattern match
var message = success.Match(
    fail => $"Error: {fail.Message}",
    value => $"Success: {value}"
);

// Asynchronous pattern matching
await error.MatchAsync(
    async fail => { await Task.Delay(10); return $"Async error: {fail.Message}"; },
    async value => { await Task.Delay(10); return $"Async success: {value}"; }
);

// Mapping success value
SResult<string> mapped = success.Map(val => $"Result: {val}");

// Async mapping
SResult<string> asyncMapped = await success.MapAsync(async val => {
    await Task.Delay(10);
    return $"Result: {val}";
});

// Check result type
if (success.IsSuccess)
    Console.WriteLine($"Success value: {success.SuccessValue}");
if (error.IsFail)
    Console.WriteLine($"Error value: {error.ErrorValue}");

Bespoke Errors

ARPL allows you to create custom error types by extending the Error class. This enables you to create domain-specific errors that carry meaningful context for your application:

public record NotFoundError : Error
{
    public NotFoundError(string entityType, string identifier)
    {
        EntityType = entityType;
        Identifier = identifier;
    }

    public string EntityType { get; }
    public string Identifier { get; }
    public override string Message => $"{EntityType} with id {Identifier} was not found";
    public override bool IsExpected => true;
}

// Usage example:
public async Task<SResult<User>> GetUserById(string userId)
{
    var user = await _repository.FindUserById(userId);
    if (user == null)
        return SResult<User>.Error(new NotFoundError("User", userId));

    return SResult<User>.Success(user);
}

// Pattern matching with custom error
var result = await GetUserById("123");
var message = result.Match(
    fail => fail is NotFoundError nf 
        ? $"Could not find {nf.EntityType} {nf.Identifier}" 
        : "Unknown error",
    success => $"Found user: {success.Name}"
);

Bespoke errors provide several benefits:

  1. Type-safe error handling with pattern matching
  2. Rich error context specific to your domain
  3. Clear distinction between expected and unexpected errors
  4. Consistent error handling across your application

Implicit Conversions

ARPL supports implicit conversions between Either<Error,R> and SResult<R>, making it seamless to work with both types:

// Convert from Either to SResult
Either<Error, int> either = Either<Error, int>.Right(42);
SResult<int> result = either; // Implicit conversion

// Convert from SResult to Either
SResult<int> sresult = SResult<int>.Success(42);
Either<Error, int> converted = sresult; // Implicit conversion

Note: The implicit conversion only works for Either<Error, R> and SResult<R>. Attempting to convert other types will throw an exception.

Best Practices

  1. Use Either<L,R> when you need a generic discriminated union
  2. Use SResult<R> for specific success/error handling scenarios
  3. Leverage pattern matching with Match for clean and safe value handling
  4. Prefer using the type system for error handling instead of exceptions

StaticFactory Helpers

For a more functional and concise style, ARPL provides the StaticFactory class, which offers utility methods to create instances of SResult and Either in a direct and expressive way:

using static Arpl.Core.StaticFactory;

// Create a success result
var success = Success(42); // SResult<int>

// Create a failure result
var fail = Fail<int>(new Error("fail")); // SResult<int>

// Create an Either with a left value
var left = Left<string, int>("error"); // Either<string, int>

// Create an Either with a right value
var right = Right<string, int>(42); // Either<string, int>

Available Methods

  • Success<T>(T value): Creates a successful SResult<T>.
  • Fail<T>(Error value): Creates a failed SResult<T>.
  • Left<L, R>(L value): Creates an Either<L, R> with a left value.
  • Right<L, R>(R value): Creates an Either<L, R> with a right value.

These methods make it easier to create values for functional flows and tests, making your code cleaner and more readable.

Contributing 🤝

Contributions are welcome! Feel free to submit issues and pull requests.

License 📄

This project is licensed under the MIT License - see the LICENSE file for details.


Disclaimer: This README was generated and reviewed with the assistance of Windsurf AI.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ARPL:

Package Downloads
ARPL.AspNetCore

A lightweight C# library providing robust discriminated unions for error handling and functional programming patterns. ARPL offers two main types: Either<L,R> for generic discriminated unions and SResult<R> for specialized success/error handling.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.12 25 9/28/2025
1.0.11 114 9/13/2025
1.0.10 151 5/2/2025
1.0.9 162 5/1/2025
1.0.8 183 4/30/2025
1.0.7 166 4/30/2025
1.0.6 171 4/29/2025
1.0.5 106 4/26/2025
1.0.5-rc 165 4/25/2025
1.0.4 169 4/25/2025
1.0.3 177 4/24/2025
1.0.2 121 4/19/2025
1.0.1 215 4/16/2025
1.0.0 228 4/15/2025