Nest.JS | Monads -> Either
The Either
monad, also known as the Result
monad, is a monad that is used to represent computations that can have one of two possible outcomes: a value of type Left
or a value of type Right
. The Left
type is typically used to represent an error or failure, while the Right
type is used to represent a successful computation.
The Either
monad is typically implemented as an object that has two subtypes: Left
and Right
. The Left
subtype holds an error value, while the Right
subtype holds a successful value.
Here’s an example of the Either
monad in JavaScript:
class Left {
constructor(value) {
this.value = value;
}
map(f) {
return this;
}
chain(f) {
return this;
}
getOrElse(defaultValue) {
return defaultValue;
}
}
class Right {
constructor(value) {
this.value = value;
}
map(f) {
return new Right(f(this.value));
}
chain(f) {
return f(this.value);
}
getOrElse(defaultValue) {
return this.value;
}
}
In this example, the Left
class takes an error value in its constructor and has a method getOrElse
that allows you to get the wrapped error value. The Right
class takes a successful value in its constructor, and has methods map
, chain
and getOrElse
that allow you to transform the wrapped value and chain multiple computations together.
For example, you could create a Right
that wraps a number and then use the map
method to increment that number, or you could create a Left
that wraps an error message, and then use the getOrElse
method to handle the error. You could then chain multiple of these Right
and Left
together to create a more complex computation, without having to manually check for the presence of a value or an error at each step.
In Nest.js, the Either
Monad is a Monad that allows you to handle errors and return values in a functional way. It can be used to represent the result of a computation that can either be a success (a right value) or a failure (a left value).
Here’s an example of how you could use the Either
Monad in Nest.js:
import { Injectable } from '@nestjs/common';
import { Either, left, right } from 'fp-ts/lib/Either';
@Injectable()
export class MyService {
public findUserById(id: number): Either<Error, User> {
const user = findUserInDB(id);
if (user) {
return right(user);
} else {
return left(new Error('User not found'));
}
}
}
In this example, the MyService
class has a method findUserById(id: number)
that returns an instance of the Either
Monad, which is either a right
value (a User
object) if one is found by the findUserInDB(id)
function, or a left
value (an Error
object) if no user is found.
You can use the .fold()
method to attach a callback function that will be invoked with the value of the Either
Monad.myService.findUserById(1)
.fold(error => console.log(error), user => console.log(user))
You can also use the .map()
function to transform the wrapped value if it exists, and .chain()
function to chain multiple Either computations. The .map()
function will only be called on the right
value, and the .chain()
function will only be called on the right
value.
It’s important to note that this example is a basic one and doesn’t demonstrate the full power of Monads in functional programming. Monads can be used to handle various cases like error handling, chaining multiple computations and more, it’s best to understand the problem and use cases before applying monads.