Reference: https://bartoszmilewski.com/2015/01/20/functors/
Reference: https://www.amazon.com/Category-Theory-Oxford-Logic-Guides/dp/0199237182
A functor F : C → D
between categories C and D is a mapping of objects to
objects and arrows to arrows, in such a way that
F(f : A → B) = F(f) : F(A) → F(B),F(1A) = 1F(A),F(g . f) = F(g) . F(f).
That is, F preserves:
- domains and codomains,
- identity arrows,
- and compostion.
Optional itself is not a type, it’s a type constructor.
You have to give it a type argument, like Integer or Boolean,
in order to turn it into a type. Optional without any
argument represents a function on types. But can we
turn Optional into a functor?
Type constructor Optional together with the function
map :: (a -> b) -> Optional a -> Optional b should
form a functor.
- define functions and its composition
Function<Integer, Integer> nullFunction = i -> null; Function<Integer, String> toString = i -> nonNull(i) ? String.valueOf(i) : "null"; Function<Integer, String> composition = nullFunction.andThen(toString); - java
Optionaldoes not follow composition rulesassertNotEquals(Optional.of(1).map(composition), Optional.of(1).map(nullFunction).map(toString)); - java
Optionalfollows composition rules when treated as streamassertEquals(Optional.of(1).stream().map(composition).findAny(), Optional.of(1).stream().map(nullFunction).map(toString).findAny()); - vavr
Optionfollows composition rulesassertEquals(Option.of(1).map(composition), Option.of(1).map(nullFunction).map(toString));
map :: (a -> b) -> Option a -> Option b
map _ None = None
map f (Some x) = Some (f x)
@Override
default <U> Option<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper, "mapper is null");
return isEmpty() ? none() : some(mapper.apply(get()));
}
map id = idNonemap id None = { definition of map } None = { definition of id } id NoneSomemap id (Some x) = { definition of map } Some (id x) = { definition of id } Some x = { definition of id } id (Some x)
map (g . f) = map g . map fNonemap (g . f) None = { definition of map } None = { definition of map } map g None = { definition of map } map g (map f None)Somemap (g . f) (Some x) = { definition of map } Some ((g . f) x) = { definition of map } map g (Some (f x)) = { definition of map } map g (map f (Some x)) = { definition of composition } (map g . map f) (Some x)