What is a monad?
A monad is a triple (T, η, μ)
where
T
is an endofunctorT: X -> X
andη: I -> T
andμ: T x T -> T
are 2 natural transformations satisfying these laws:- Identity law:
μ(η(T)) = T = μ(T(η))
- Associative law:
μ(μ(T × T) × T)) = μ(T × μ(T × T))
- Identity law:
In other words:
a monad in X is just a monoid in the category of endofunctors of X, with
- product × replaced by composition of endofunctors and
- unit set by the identity endofunctor
In other words:
A monad
- is a structure that
- puts a value
- in a computational context
And therefore:
- Reduce code duplication
- Improve maintainability
- Increase readability
- Remove side effects
- Hide complexity
- Encapusalate implementation details
- Allow composability
##Monadic Methods##
M<A> unit(A a);
M<B> bind(M<A> ma, Function<A, M<B>> f);
interface M {
M<B> map(Function<A, B> f);
//{
// // For every monad, map can be defined as a combination of flatMap and unit
// return flatMap( x -> unit( f.apply(x) ) );
//}
M<B> flatMap(Function<A, M<B>> f);
}
public class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>(null);
private final T value;
private Optional(T value) {
this.value = value;
}
public<U> Optional<U> map (Function<? super T, ? extends U> f) {
return value == null ? EMPTY : new Optional(f.apply(value));
}
public<U> Optional<U> flatMap (Function<? super T, Optional<U>> f) {
return value == null ? EMPTY : f.apply(value);
}
}
public class Optional {
private static final Optional<?> EMPTY = new Optional<>(null);
private final T value;
private Optional(T value) {
this.value = value;
}
public<U> Optional<U> map(Function<? super T, ? extends U> f) {
return value == null ? EMPTY : new Optional(f.apply(value));
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> f) {
return value == null ? EMPTY : f.apply(value);
}
}
String getCarInsuranceName(Optional<Person> person) {
return person.flatMap(person -> person.getCar())
.flatMap(car -> car.getInsurance())
.map(insurance -> insurance.getName())
.orElse("Unknown");
}