Functors and Monads (and Optional) - nus-cs2030/2021-s1 GitHub Wiki
A functor should have:
-
private T thing
: a payload -
make(U thing)
: a constructor, usually a static method -
map(Function<? super T, ? extends U> f)
: transforms the payload, returns the transformed payload in a new Functor
An abstract Functor would be as follows:
abstract class Functor<T> {
private T thing;
abstract public <U> Functor<U> foo(Function<? super T, ? extends U> func);
}
Functors should satisfy two laws:
- identity:
make(t).map(x -> x).equals(make(t))
- associativity:
make(t).map(f).map(g).equals(make(t).map(f.andThen(g)))
A monad should have:
-
private T thing
: a payload -
make(U thing)
: a constructor, usually a static method flatmap(Function<? super T, ? extends Monad<? extends U>> func)
flatmap
helps us return a Monad<? extends U>
instead of Monad<Monad<? extends U>>
, avoiding nesting.
An abstract Monad would be as follows:
abstract class Monad<T> {
private T thing;
public <U> Monad<U> bar(Function<? super T, ? extends Monad<? extends U>> func);
}
Monads should satisfy three laws:
- left identity:
make(t).flatmap(f).equals(f(t))
- right identity:
make(t).flatmap(x -> make(x)).equals(make(t))
- associativity:
make(t).flatMap(f).flatMap(g).equals(make(t).flatmap(f.andThen(g)))
.
Is both a Functor and a Monad.
Several useful methods in Optional<T>
:
-
ofNullable(T thing)
: constructor - filter, flatmap, map
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
- for running actions with
void
return types. - or, orElse, orElseGet, orElseThrow
-
or(Supplier<? extends Optional<? extends T>> s)
: returns the Optional froms.get()
. -
orElse(T thing)
: returnsthing
, which is eagerly evaluated, unlikeor
andorElseGet
which take in Suppliers. -
orElseGet(Supplier<? extends T> supplier)
: returns type Tthing
lazily, unlikeorElse
. -
orElseThrow
- no parameter provided: throws NoSuchElementException
-
Supplier<? extends Exception>
provided: throws the exception in the parameter.
Avoid: get()
, isEmpty()
, isPresent()
, to adhere to the functional programming paradigm.