Lena 1.1.0
dotnet add package Lena --version 1.1.0
NuGet\Install-Package Lena -Version 1.1.0
<PackageReference Include="Lena" Version="1.1.0" />
<PackageVersion Include="Lena" Version="1.1.0" />
<PackageReference Include="Lena" />
paket add Lena --version 1.1.0
#r "nuget: Lena, 1.1.0"
#:package Lena@1.1.0
#addin nuget:?package=Lena&version=1.1.0
#tool nuget:?package=Lena&version=1.1.0
Lena
Lena is a comprehensive C# library providing functional programming primitives such as Option, Result, Either, and Validation types, inspired by languages like F#, Rust, and Haskell. It helps manage optional values, error handling, and functional patterns in a more expressive and type-safe way.
Features
Core Types
Option<T>: Represents an optional value, eliminating null reference exceptionsResult<T>: Represents a value or an error, for robust error handlingEither<TLeft, TRight>: Represents a value that can be one of two typesValidation<T>: Like Result but accumulates multiple errors instead of failing fastUnit: Represents a type with only one value, useful in generic contexts
Functional Programming Utilities
- LINQ support for all core types with
Select,SelectMany, andWhere - Higher-order functions: Identity, Compose, Curry, Partial application, etc.
- Async extensions for
Option<T>andResult<T> - Extension methods for common patterns like
Tap,Pipe, and sequence operations - Comprehensive collection extensions with
FirstOrNone,Choose,Traverse,Sequence
Installation
# Clone the repository
git clone <repository-url>
cd Lena
# Build the solution
dotnet build
# Run tests
dotnet test
Usage Examples
Option<T>
using Lena.Core;
// Creating Options
var some = Option<int>.Some(42);
var none = Option<int>.None();
// Using static helpers for type inference
var value = Option.Some(42); // Option<int>
var empty = Option.None<string>(); // Option<string>
// Pattern matching
var result = some.Match(
some: x => $"Value is {x}",
none: () => "No value"
); // "Value is 42"
// Functional operations
var doubled = some
.Map(x => x * 2) // Some(84)
.Filter(x => x > 50) // Some(84)
.GetOrElse(0); // 84
// Chaining with Bind (monadic bind)
Option<int> ParseInt(string s) =>
int.TryParse(s, out var i) ? Option.Some(i) : Option.None<int>();
var chain = Option.Some("42")
.Bind(ParseInt)
.Map(x => x * 2); // Some(84)
// LINQ query syntax
var query =
from x in Option.Some(21)
from y in Option.Some(21)
select x + y; // Some(42)
Result<T>
using Lena.Core;
// Creating Results
var success = Result<int>.Success(42);
var error = Result<int>.Error("Something went wrong");
// Using static helpers
var value = Result.Success(42);
var failure = Result.Error<int>("Failed");
// Safe execution
var result = Result.Try(() => int.Parse("42")); // Success(42)
var failed = Result.Try(() => int.Parse("abc")); // Error(FormatException)
// Pattern matching
var message = result.Match(
success: x => $"Got {x}",
error: ex => $"Error: {ex.Message}"
);
// Chaining operations
Result<string> ProcessValue(int x) =>
x > 0 ? Result.Success(x.ToString()) : Result.Error<string>("Must be positive");
var chain = Result.Success(42)
.Map(x => x * 2)
.Bind(ProcessValue); // Success("84")
// Convert to Option
var option = success.ToOption(); // Some(42)
Either<TLeft, TRight>
using Lena.Core;
// Creating Either values
var right = Either<string, int>.Right(42);
var left = Either<string, int>.Left("error");
// Pattern matching
var result = right.Match(
left: error => $"Error: {error}",
right: value => $"Value: {value}"
); // "Value: 42"
// Functional operations (works on Right values)
var doubled = right.Map(x => x * 2); // Right(84)
var leftStayed = left.Map(x => x * 2); // Left("error")
Extension Methods and Collections
using Lena.Core;
// Working with sequences
var numbers = new[] { "1", "2", "abc", "4" };
// Parse all numbers, filter out failures
var parsed = numbers
.Choose(s => int.TryParse(s, out var i) ? Option.Some(i) : Option.None<int>())
.ToList(); // [1, 2, 4]
// First element as Option
var first = numbers.FirstOrNone(); // Some("1")
var empty = new int[0].FirstOrNone(); // None
// Functional utilities
var result = 42
.Pipe(x => x * 2) // 84
.Tap(x => Console.WriteLine(x)) // Side effect, prints 84
.Where(x => x > 50) // Some(84)
.GetOrElse(0); // 84
Design Philosophy
Lena follows functional programming principles:
- Immutability: All types are immutable by design
- Null safety: Eliminates null reference exceptions through
Option<T> - Error handling: Railway-oriented programming with
Result<T>andValidation<T> - Composability: All operations can be chained and composed
- Type safety: Leverages C#'s type system to prevent runtime errors
Testing
Run tests with:
dotnet test
The library includes comprehensive unit tests covering core laws, edge cases, and integration scenarios.
Project Structure
Lena/Core/: Core types (Option,Result,Either,Validation,Unit)Lena/Extensions/: Extension methods for functional programming patternsLena/Functions/: Higher-order functions and utilitiesLena/Asyncs/: Async support for core typesLena.Tests/: Comprehensive unit tests
Contributing
Contributions are welcome! Please ensure all tests pass and add tests for new features.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.