Skip to content

Commit

Permalink
docs: README minors
Browse files Browse the repository at this point in the history
  • Loading branch information
MrBogomips committed Dec 20, 2023
1 parent 1891aae commit a4486a4
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -41,7 +41,7 @@ This library provides two well-known monads: `Result` and `Maybe` monads (also r

> The `Result<T>` monad is used to model operations that can fail.
>The `Maybe<T>` monad is used to model operations that can either return a value or be empty.
>The `Maybe<T>` monad is used to model operations that can optionally return a value.
Additionally, the library provides the `Error` abstract class, which complements the `Result<T>` monad and
offers an ergonomic approach to error management at an application-wide scale.
Expand All @@ -51,7 +51,7 @@ offers an ergonomic approach to error management at an application-wide scale.
The `Result<T>` 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<T>` provides a set of methods that facilitate chaining operations in a functional manner:
`Result<T>` 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<Unit>`
* `MapToUnit()` is just a shortcut for `Map(_ => { })`
Expand All @@ -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<T>`
* `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.
Expand Down Expand Up @@ -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
Expand All @@ -192,15 +192,16 @@ thrown by the application.
## Design Goals for `Maybe<T>`

Before discussing what can be achieved with the `Maybe<T>` monad, let's clarify that it is not intended as a
replacement for Nullable<T>.
replacement for `Nullable<T>`.
This is mainly due to fundamental libraries, such as Entity Framework, relying on `Nullable<T>` to model class
attributes, while support for structural types remains limited.

A pragmatic approach involves using `Nullable<T>` for modeling class attributes and `Maybe<T>` for modeling
return values and method parameters.

The advantage of using `Maybe<T>` over `Nullable<T>` is that `Maybe<T>` 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<T>` to `Maybe<T>` allows for lifting `Nullable<T>` values to `Maybe<T>`
Expand Down

0 comments on commit a4486a4

Please sign in to comment.