From a4486a4f3baf259889c1af301139f705fc9c2c94 Mon Sep 17 00:00:00 2001 From: Giovanni Costagliola Date: Wed, 20 Dec 2023 13:07:12 +0100 Subject: [PATCH] docs: README minors --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index da8d988..5cc6a2f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _Yet another functional library for C#_ ## Quickstart -Install from Nuget and enjoy! +Install from Nuget and enjoy it! ```shell dotnet add package Bogoware.Monads @@ -16,14 +16,14 @@ dotnet add package Bogoware.Monads ## Introduction to Monads -Monads are a powerful tool for modeling operations in a functional way, making them a cornerstone +Monads are powerful tools for modeling operations in a functional way, making them a cornerstone of functional programming. While we won't delve into a detailed explanation of monads and their inner -workings in this document, there are numerous resources available online that approach the topic +workings, there are numerous resources available online that approach the topic from different perspectives. -For the purpose of this introduction, we can consider monads as a type of "safe container" that encapsulates +For the purpose of this introduction, we can consider monads as am abstraction of _safe container_ that encapsulates the result of an operation. They provide methods that enable manipulation of the result in a safe manner, -ensuring that the operation executes only if it succeeds. +ensuring that the execution flow follows the "happy" path in case of success and the "unhappy" path in case of failure. This model is also known as _railway-oriented programming_. By employing monads, code can be protected from further processing in case of errors or missing data. Adopting a functional approach offers benefits such as increased readability, improved reasoning capabilities, @@ -41,7 +41,7 @@ This library provides two well-known monads: `Result` and `Maybe` monads (also r > The `Result` monad is used to model operations that can fail. ->The `Maybe` monad is used to model operations that can either return a value or be empty. +>The `Maybe` monad is used to model operations that can optionally return a value. Additionally, the library provides the `Error` abstract class, which complements the `Result` monad and offers an ergonomic approach to error management at an application-wide scale. @@ -51,7 +51,7 @@ offers an ergonomic approach to error management at an application-wide scale. The `Result` monad is designed for modeling operations that can either fail or return a value. It is a generic type, with `T` representing the type of the value returned by the successful operation. -`Result` provides a set of methods that facilitate chaining operations in a functional manner: +`Result` provides a set of methods that facilitate chaining operations in a functional way: * `Map`: Allows transformation of the value returned by the operation, representing the "happy" flow. * `Map` to void functor will map to `Result` * `MapToUnit()` is just a shortcut for `Map(_ => { })` @@ -61,8 +61,8 @@ It is a generic type, with `T` representing the type of the value returned by th * `Match`: Facilitates handling of the operation's result by providing separate paths for the "happy" and "unhappy" flows. * `RecoverWith`: Provides a way to recover from an error by returning a `Result` * `Ensure`: Allows asserting a condition on the value returned by the operation. -* `ExecuteIfSuccess`: Executes if the operation succeeds. It is typically used for side effects. -* `ExecuteIfFailure`: Executes if the operation fails. It is typically used for side effects. +* `ExecuteIfSuccess`: Executes if the operation succeeds. It is typically used to generate side effects. +* `ExecuteIfFailure`: Executes if the operation fails. It is typically used to generate side effects. There are also some unsafe methods intended to support developers who are less familiar with the functional approach and may need to resort to a procedural style to achieve their goals. @@ -183,7 +183,7 @@ public class InvalidOperationError : ApplicationError } ``` -As demonstrated in the project [FluentValidationSample](./samples/FluentValidationSample) the `FluentValidation` library +As demonstrated in the project [FluentValidationSample](./sample/FluentValidationSample) the `FluentValidation` library can be used to model validation errors. In contrast to `LogicError`s, `RuntimeError`s are generated by the `Result.Execute()` methods to encapsulate exceptions @@ -192,15 +192,16 @@ thrown by the application. ## Design Goals for `Maybe` Before discussing what can be achieved with the `Maybe` monad, let's clarify that it is not intended as a -replacement for Nullable. +replacement for `Nullable`. This is mainly due to fundamental libraries, such as Entity Framework, relying on `Nullable` to model class attributes, while support for structural types remains limited. + A pragmatic approach involves using `Nullable` for modeling class attributes and `Maybe` for modeling return values and method parameters. The advantage of using `Maybe` over `Nullable` is that `Maybe` provides a set of methods that enable chaining operations in a functional manner. -This becomes particularly useful when dealing with operations that can either return a value or be empty, +This becomes particularly useful when dealing with operations that can optionally return a value, such as querying a database. The implicit conversion from `Nullable` to `Maybe` allows for lifting `Nullable` values to `Maybe`