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
- 543