### Setup and Build .NET Project Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Commands to clone the repository, navigate to the project directory, and build the .NET solution. This is a one-time setup process for working with the code samples. ```bash $ git clone git@github.com:la-yumba/functional-csharp-code-2.git $ cd functional-csharp-code-2 $ dotnet build ``` -------------------------------- ### Run .NET Examples Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Command to run specific examples from the 'Examples' project. This allows users to see code samples in action and debug them. ```bash $ cd Examples $ dotnet run Greetings ``` -------------------------------- ### Functional Programming Example in C# REPL Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Demonstrates basic functional programming concepts in the C# REPL using the 'LaYumba.Functional' library. It shows how to apply functions within 'Option' types. ```csharp > var plus = (int a, int b) => a + b; > Some(plus).Apply(1).Apply(2) [Some(3)] > Some(plus).Apply(1).Apply(None) [None] ``` -------------------------------- ### Map, Bind, and Apply - Core Functional Operations in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt These fundamental functional operations are essential for composing operations within container types. Map transforms a value inside a container (Functor), Bind chains operations that return wrapped values (Monad), and Apply facilitates applicative-style composition for multi-argument functions. Examples are shown using Option and IEnumerable from LaYumba.Functional. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // MAP: Transform the inner value (Functor) Option opt = Some(5); Option doubled = opt.Map(x => x * 2); // Some(10) IEnumerable nums = List(1, 2, 3); IEnumerable squares = nums.Map(x => x * x); // [1, 4, 9] // BIND: Chain operations returning wrapped values (Monad) Option ParseInt(string s) => Int.Parse(s); Option Sqrt(int n) => n >= 0 ? Some(Math.Sqrt(n)) : None; Option result = Some("16") .Bind(ParseInt) // Some(16) .Bind(Sqrt); // Some(4.0) // APPLY: Combine multiple wrapped values (Applicative) var add = (int a, int b) => a + b; Option sum = Some(add) .Apply(Some(3)) .Apply(Some(4)); // Some(7) // If any argument is None, result is None Option noSum = Some(add) .Apply(Some(3)) .Apply(None); // None // Multi-argument curried application var multiply = (int a, int b, int c) => a * b * c; Option product = Some(multiply) .Apply(Some(2)) .Apply(Some(3)) .Apply(Some(4)); // Some(24) ``` -------------------------------- ### Run Exercises in C# Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Commands to navigate to the 'Exercises' project, modify 'Program.cs' to specify the class to run, and execute the exercises using the 'dotnet run' command. ```bash $ cd Exercises $ dotnet run ``` -------------------------------- ### Run .NET Tests Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Command to execute tests within the .NET solution. This can be run from the root directory or specific test project directories. ```bash $ cd LaYumba.Functional.Tests $ dotnet test ``` -------------------------------- ### Load LaYumba.Functional Library in C# REPL Source: https://github.com/la-yumba/functional-csharp-code-2/blob/master/README.md Instructions for loading the 'LaYumba.Functional' library into the C# Interactive REPL. This involves referencing the DLL and importing necessary namespaces for functional programming constructs. ```csharp #r "functional-csharp-code-2\LaYumba.Functional\bin\Debug\net6.0\LaYumba.Functional.dll" using LaYumba.Functional; using static LaYumba.Functional.F; ``` -------------------------------- ### Functional Exception Handling with Try and Exceptional in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Demonstrates how to use `Try` and `Exceptional` for functional exception handling. It covers lazy execution of potentially throwing operations, capturing exceptions as values, chaining operations using LINQ-style syntax, and pattern matching on the `Exceptional` type. Dependencies include `LaYumba.Functional`. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Try: A delegate that may throw, executed lazily Try ParseInt(string s) => Try(() => int.Parse(s)); // Running Try produces Exceptional Exceptional result1 = ParseInt("123").Run(); // Success(123) Exceptional result2 = ParseInt("abc").Run(); // Exception(FormatException) // Chaining Try operations Try Divide(int x, int y) => Try(() => (double)x / y); Try Calculate(string num, string denom) => from n in ParseInt(num) from d in ParseInt(denom) from r in Divide(n, d) select r; var calc1 = Calculate("100", "4").Run(); // Success(25.0) var calc2 = Calculate("100", "0").Run(); // Success(Infinity) var calc3 = Calculate("abc", "4").Run(); // Exception(FormatException) // Pattern matching on Exceptional string message = result2.Match( Exception: ex => $"Error: {ex.Message}", Success: val => $"Parsed: {val}"); // Map and Bind on Exceptional Exceptional doubled = result1.Map(x => x * 2); // Success(246) Exceptional chained = result1.Bind(x => x > 100 ? Exceptional(x) : new ArgumentException("Too small")); ``` -------------------------------- ### Safe Dictionary Lookups with Option in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Introduces the `Lookup` extension method for `Dictionary` which provides safe access to dictionary elements. Instead of throwing a `KeyNotFoundException`, it returns an `Option`, representing either the presence of a value (`Some`) or its absence (`None`). This enables chaining operations and combining lookups functionally. Dependencies include `LaYumba.Functional`. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; var cache = new Dictionary { ["alice"] = 100, ["bob"] = 200 }; // Safe lookup returning Option Option aliceScore = cache.Lookup("alice"); // Some(100) Option charlieScore = cache.Lookup("charlie"); // None // Chaining with other operations string message = cache.Lookup("bob") .Map(score => score * 2) .Match( None: () => "User not found", Some: doubled => $"Doubled score: {doubled}"); // "Doubled score: 400" // Combining multiple lookups var users = new Dictionary { [1] = "Alice", [2] = "Bob" }; var scores = new Dictionary { ["Alice"] = 95, ["Bob"] = 87 }; Option GetUserScore(int userId) => users.Lookup(userId) .Bind(name => scores.Lookup(name)); var score1 = GetUserScore(1); // Some(95) var score2 = GetUserScore(99); // None ``` -------------------------------- ### Curry and Partial Application - Function Transformation in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Currying transforms a function that takes multiple arguments into a sequence of functions, each taking a single argument. Partial application fixes some of these arguments, creating a new function with a reduced arity. These techniques, demonstrated using LaYumba.Functional, are powerful for creating specialized functions and improving code readability. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Original multi-argument function Func greet = (greeting, name) => $"{greeting}, {name}!"; // Currying: transform to chain of single-argument functions Func> curriedGreet = greet.Curry(); Func greetHello = curriedGreet("Hello"); string result1 = greetHello("World"); // "Hello, World!" // Partial application with Apply Func greetHi = greet.Apply("Hi"); string result2 = greetHi("Alice"); // "Hi, Alice!" // Three-argument function Func volume = (l, w, h) => l * w * h; // Curry first argument only Func> withLength = volume.CurryFirst(); Func boxWith10 = withLength(10); int vol = boxWith10(5, 3); // 150 // Practical example: creating specialized functions var names = new[] { "Tristan", "Ivan", "Alice" }; var formalGreet = greet.Apply("Good evening"); var casualGreet = greet.Apply("Hey"); names.Map(formalGreet).ForEach(Console.WriteLine); // Good evening, Tristan! // Good evening, Ivan! // Good evening, Alice! names.Map(casualGreet).ForEach(Console.WriteLine); // Hey, Tristan! // Hey, Ivan! // Hey, Alice! ``` -------------------------------- ### Function Composition and Piping Utilities in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Provides utilities for function composition (Compose) and piping values through transformation chains (Pipe). Includes Tap for side effects and Using for IDisposable management. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Function composition with Compose Func trim = s => s.Trim(); Func toLower = s => s.ToLower(); Func length = s => s.Length; // g.Compose(f) creates: x => g(f(x)) Func normalize = toLower.Compose(trim); Func normalizedLength = length.Compose(normalize); int len = normalizedLength(" HELLO "); // 5 // Pipe: pass value through function chain string result = " HELLO WORLD " .Pipe(s => s.Trim()) .Pipe(s => s.ToLower()) .Pipe(s => s.Replace(" ", "-")); // "hello-world" // Tap: execute side effect and return original value Func logAndReturn = Tap( s => Console.WriteLine($"Processing: {s}")); string processed = "data" .Pipe(logAndReturn) // logs "Processing: data" .Pipe(s => s.ToUpper()); // "DATA" // Using: functional wrapper for IDisposable string content = Using( () => new StreamReader("file.txt"), reader => reader.ReadToEnd()); // Range: generate sequences IEnumerable nums = Range(1, 5); // [1, 2, 3, 4, 5] IEnumerable chars = Range('a', 'e'); // ['a', 'b', 'c', 'd', 'e'] ``` -------------------------------- ### Agent Actor Model Concurrency in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Demonstrates the Agent type for actor-based concurrency, enabling thread-safe message processing. Supports stateless, stateful, and two-way agents, as well as asynchronous operations. ```csharp using LaYumba.Functional; // Stateless agent: fire-and-forget message processing Agent logger = Agent.Start( msg => Console.WriteLine($"[LOG] {msg}")); logger.Tell("Application started"); logger.Tell("Processing request"); // Stateful agent: maintains state across messages Agent counter = Agent.Start( initialState: 0, process: (count, msg) => count + msg); counter.Tell(1); // state becomes 1 counter.Tell(5); // state becomes 6 counter.Tell(-2); // state becomes 4 // Two-way agent: returns response for each message Agent wordCounter = Agent.Start( initialState: 0, process: (totalWords, text) => { int words = text.Split(' ').Length; return (totalWords + words, words); }); Task count1 = wordCounter.Tell("Hello world"); // returns 2 Task count2 = wordCounter.Tell("One two three"); // returns 3 // Async stateful agent Agent, string> asyncStore = Agent.Start, string>( initialState: new List(), process: async (items, newItem) => { await Task.Delay(100); // simulate async work return items.Append(newItem).ToList(); }); ``` -------------------------------- ### Task Extensions for Async Functional Composition in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Extends Task with functional composition methods like Map, Bind, Apply, and LINQ support. Enables chaining and combining asynchronous operations in a functional style. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Async: wrap value in completed Task Task asyncValue = Async(42); // Map: transform async result Task doubled = asyncValue.Map(x => x * 2); // Task(84) // Bind: chain async operations async Task FetchUser(int id) => $"User{id}"; async Task FetchScore(string user) => user.Length * 10; Task GetUserScore(int id) => FetchUser(id).Bind(FetchScore); // Task(50) for id=1 // Apply: combine parallel async operations Func add = (a, b) => a + b; Task sum = Async(add) .Apply(FetchScore("Alice")) .Apply(FetchScore("Bob")); // Both fetches run in parallel, result combined // LINQ query syntax for async Task GetGreeting(int userId) => from user in FetchUser(userId) from score in FetchScore(user) select $"{user} has score {score}"; // Error recovery Task FetchWithFallback(int id) => FetchScore($"User{id}") .Recover(ex => -1) // return -1 on any exception .OrElse(() => Async(0)); // fallback task on failure // ForEach: side effects on completion asyncValue.ForEach(val => Console.WriteLine($"Got: {val}")); ``` -------------------------------- ### Functional Collection Operations with IEnumerable Extensions in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt Extends `IEnumerable` with functional methods like `Map`, `Bind`, `Head`, `Partition`, and `Traverse`. These methods allow for more expressive collection processing, including transformations, flattening, safe element access, splitting collections based on predicates, and converting collections of effectful types to effectful collections. Dependencies include `LaYumba.Functional`. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // List creation IEnumerable numbers = List(1, 2, 3, 4, 5); // Map: transform each element IEnumerable doubled = numbers.Map(x => x * 2); // [2, 4, 6, 8, 10] // Bind (flatMap): flatten nested collections IEnumerable Expand(int n) => Enumerable.Range(1, n); IEnumerable expanded = List(2, 3).Bind(Expand); // [1, 2, 1, 2, 3] // Head: safely get first element as Option Option first = numbers.Head(); // Some(1) Option empty = List().Head(); // None // Find: first element matching predicate Option found = numbers.Find(x => x > 3); // Some(4) // Partition: split by predicate var (evens, odds) = numbers.Partition(x => x % 2 == 0); // evens: [2, 4], odds: [1, 3, 5] // ForEach: side effects on each element numbers.ForEach(x => Console.WriteLine(x)); // Traverse: convert IEnumerable> to Option> var inputs = new[] { "1", "2", "3" }; Option> allValid = inputs.Traverse(Int.Parse); // Some([1, 2, 3]) var mixedInputs = new[] { "1", "abc", "3" }; Option> hasInvalid = mixedInputs.Traverse(Int.Parse); // None // Traverse with Validation (accumulates errors) Validation ParseDouble(string s) => Double.Parse(s).Match( () => Error($"'{s}' is not a valid number"), d => Valid(d)); string input = "1, 2, three"; Validation> validated = input.Split(',') .Map(s => s.Trim()) .Traverse(ParseDouble); // Invalid(["'three' is not a valid number"]) ``` -------------------------------- ### Representing Optional Values with Option in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt The Option type in LaYumba.Functional replaces null references by explicitly representing the presence (Some) or absence (None) of a value. It facilitates safe null handling through pattern matching, transformations with Map, chaining with Bind, and providing default values. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Creating Option values Option some = Some("John"); // Some("John") Option none = None; // None // Pattern matching with Match string greeting = some.Match( None: () => "Hello, stranger", Some: name => $"Hello, {name}"); // "Hello, John" // Transforming with Map var greet = (string name) => $"Hello, {name}"; Option result = some.Map(greet); // Some("Hello, John") Option empty = none.Map(greet); // None // Chaining with Bind (flatMap) Option ParseAge(string s) => Int.Parse(s); Option age = Some("25").Bind(ParseAge); // Some(25) Option invalid = Some("abc").Bind(ParseAge); // None // Default values string name = none.GetOrElse("Anonymous"); // "Anonymous" Option fallback = none.OrElse(Some("Default")); // Some("Default") // LINQ query syntax var person = from n in Some("Alice") from a in Some(30) select $"{n} is {a} years old"; // Some("Alice is 30 years old") ``` -------------------------------- ### Validation - Accumulating Multiple Errors in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt The Validation type allows for the accumulation of multiple errors, unlike types that short-circuit on the first error. This is particularly useful for scenarios like form validation where all issues need to be reported simultaneously. It leverages static methods from LaYumba.Functional.F for creating valid and invalid states and the Apply method for combining multiple validations. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; // Creating Validation values Validation valid = Valid(42); Validation invalid = Invalid(Error("Value is required")); // Validation functions Validation ValidateName(string name) => string.IsNullOrWhiteSpace(name) ? Invalid(Error("Name cannot be empty")) : Valid(name.Trim()); Validation ValidateAge(int age) => age < 0 ? Invalid(Error("Age cannot be negative")) : age > 150 ? Invalid(Error("Age cannot exceed 150")) : Valid(age); Validation ValidateEmail(string email) => email.Contains("@") ? Valid(email) : Invalid(Error("Email must contain @")); // Combining validations with Apply (applicative) record Person(string Name, int Age, string Email); Func createPerson = (name, age, email) => new Person(name, age, email); Validation ValidatePerson(string name, int age, string email) => Valid(createPerson) .Apply(ValidateName(name)) .Apply(ValidateAge(age)) .Apply(ValidateEmail(email)); // All errors accumulated var result1 = ValidatePerson("", -5, "invalid"); // Invalid([Name cannot be empty, Age cannot be negative, Email must contain @]) var result2 = ValidatePerson("John", 30, "john@example.com"); // Valid(Person { Name = John, Age = 30, Email = john@example.com }) // Pattern matching string output = result1.Match( Invalid: errors => string.Join("; ", errors), Valid: person => $"Created: {person.Name}"); ``` -------------------------------- ### Handling Errors with Either in C# Source: https://context7.com/la-yumba/functional-csharp-code-2/llms.txt The Either type from LaYumba.Functional represents a value that is either a Left (typically an error) or a Right (typically a success). It enables explicit error handling without exceptions, making error cases visible in function signatures and allowing for functional chaining of operations. ```csharp using LaYumba.Functional; using static LaYumba.Functional.F; using static System.Math; // Creating Either values Either success = Right(3.14); Either failure = Left("Division by zero"); // Function returning Either for error handling Either Divide(double x, double y) { if (y == 0) return "Cannot divide by zero"; return x / y; } Either Sqrt(double x) { if (x < 0) return "Cannot take square root of negative number"; return Math.Sqrt(x); } // Pattern matching string message = Divide(10, 2).Match( Left: err => $"Error: {err}", Right: val => $"Result: {val}"); // "Result: 5" // Chaining operations with Bind Either Calculate(double x, double y) => Divide(x, y) .Bind(Sqrt) .Map(result => Math.Round(result, 2)); var result1 = Calculate(16, 4); // Right(2) var result2 = Calculate(10, 0); // Left("Cannot divide by zero") var result3 = Calculate(-16, 4); // Left("Cannot take square root of negative number") // LINQ query syntax var computation = from a in Divide(100, 4) from b in Sqrt(a) select b * 2; // Right(10) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.