Monads with Java

Monad???

Basics

Integer value = 2;

>> 2

Integer value = 2;

Function<Integer, Integer> plus = n -> n + 3;
plus.apply(value);

>> 5

Optional<Integer> value = Optional.of(2);

>> Optional[2]

Optional<Integer> value = Optional.of(2);
value.isPresent();

>> true

Cat in a Box

Functors

Optional<Integer> value = Optional.of(2);

Function<Integer, Integer> plus = n -> n + 3;
plus.apply(value);

>> error!

Optional<Integer> value = Optional.of(2);

Function<Integer, Integer> plus = n -> n + 3;
value.map(plus);

>> Optional[5]

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}
Optional.ofNullable(mapper.apply(value));
---
value.map(plus);

>> Optional[5]

if (!isPresent()) return empty();
---
Optional<Integer> value = Optional.empty();
value.map(plus);

>> Optional.empty

Optional<Integer> value = Optional.of(2);

Function<Integer, Integer> plus2 = n -> n + 2;
Function<Integer, Integer> plus3 = n -> n + 3;

value.of(10).map(plus2).map(plus3);

>> Optional[15]

Optional<Integer> value = Optional.of(10);

value.map(n -> n + 2).map(n -> n + 3);

>> Optional[15]

Function<Integer, Optional<Integer>> half = n -> {
    if (n > 0 && (n % 2) == 0) {
        return Optional.of(n / 2);
    }

    return Optional.empty();
};

>> 

Optional<Integer> value = Optional.of(3);
value.map(half).map(helf);

>> Error:(21, 51) java: method map in class java.util.Optional<T> cannot be applied to given types;

Cat in a Box, in a Box

Monads

Optional<Integer> value = Optional.of(3);
value.flatMap(half);

>> Optional.empty

>>=

Optional<Integer> value = Optional.of(4);
value.flatMap(half);

>> Optional[2]

>>=

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}
Optional.of(20)
    .flatMap(half)
    .flatMap(half)
    .flatMap(half);

>> Optional.empty

Optional.of("CAB")
    .map(s -> s + "D")
    .map(s -> s + "e")
    .map(s -> s.split(""))
    .map(s -> Stream.of(s)
                .sorted()
                .collect(Collectors.joining()))
    .map(String::toUpperCase)
    .orElse("EMPTY");

>> ABCDE

Optional

Optional.ofNullable(null)
    .map(s -> s + "D")
    .map(s -> s + "e")
    .map(s -> s.split(""))
    .map(s -> Stream.of(s)
                .sorted()
                .collect(Collectors.joining()))
    .map(String::toUpperCase)
    .orElse("EMPTY");

>> EMPTY

Optional

Stream.of(5, 1, 2, 3, 4)
    .filter(n -> n > 3)
    .map(n -> n + 1)
    .sorted()
    .findFirst()
    .ifPresent(System.out::println);

>> 5

Stream

Stream.of(new String[] {"AbC", "BCd", null, "CdE"})
    .filter(Objects::nonNull)
    .map(String::toUpperCase)
    .map(s -> s.split(""))
    .flatMap(Stream::of)
    .distinct()
    .collect(Collectors.toList());

>> [A, B, C, D, E]

Stream

CompletableFuture
    .supplyAsync(() -> String.format("Num:%d", 3))
    .thenApply(s -> String.format("%s::apply1", s))
    .thenApplyAsync(s -> String.format("%s::apply2", s))
    .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + "::Compose"))
    .join();

>> Num:3::apply1::apply2::Compose

CompletableFuture

Flowable.range(1, 10)
  .parallel()
  .runOn(Schedulers.computation())
  .map(v -> v * v)
  .sequential()
  .blockingSubscribe(System.out::println);
https://github.com/ReactiveX/RxJava

RxJava

root@USER:~# ls -al | grep .bash
-rw------- 1 root root    0 Oct 26 17:16 .bash_history
-rw-r--r-- 1 root root 3106 Oct 23  2015 .bashrc

Unix pipe

TL;DR

  • Functor와 Monad는 값과 상태를 담는 일종의 Type이다.

TL;DR

  • Functor와 Monad는 값과 상태를 담는 일종의 Type이다.
  • Functor는 map()으로 상자안의 값에 함수를 적용한다.
  • Monad는 flatMap()으로 값이 들어있는 상자를 받아 함수를 적용한다.

TL;DR

  • Functor와 Monad는 값과 상태를 담는 일종의 Type이다.
  • Functor는 map()으로 상자안의 값에 함수를 적용한다.
  • Monad는 flatMap()으로 값이 들어있는 상자를 받아 함수를 적용한다.
  • 여러 개별적인 동작을 하나의 방식으로 일반화 해준다.
  • Monad를 적용한 다른 기능(RxJava 등)에 대한 학습비용이 적다.

TL;DR

END

Monads with Java

By serivires

Monads with Java

  • 535