Create a gist now

Instantly share code, notes, and snippets.

@nbardiuk /App.java
Last active Nov 8, 2015

What would you like to do?
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
public class App {
public static void main(String[] args) {
App app = new App();
app.mapExample();
app.flatMapExample();
app.optionalAdd();
app.optionalCompute();
app.optionalStreams();
app.optionalFlatten();
}
void mapExample() {
Wrap<Integer> a = Wrap.of(1); // Wrap(value=1
Wrap<Integer> b = a.map(i -> i + 9); // Wrap(value=10)
Wrap<Integer> c = b.map(i -> i * 11); // Wrap(value=110)
a.map(i -> i * 10).map(i -> i + 11); // Wrap(value=21)
// System.out.println(a);
// System.out.println(b);
// System.out.println(c);
// System.out.println(a.map(i -> i * 10).map(i -> i + 11));
}
void flatMapExample() {
Wrap<Integer> a = Wrap.of(1); // Wrap(value=1)
a.flatMap(this::inc); // Wrap(value=2)
a.flatMap(this::inc).flatMap(this::inc); // Wrap(value=3)
// System.out.println(a);
// System.out.println(a.flatMap(this::inc));
// System.out.println(a.flatMap(this::inc).flatMap(this::inc));
}
Wrap<Integer> inc(Integer x) {
return Wrap.of(x + 1);
}
void optionalAdd() {
Optional<Integer> a = Optional.of(13);
Optional<Integer> b = Optional.of(42);
add(a, b); // Optional[55]
add(a, Optional.empty()); // Optional.empty
add(Optional.empty(), b); // Optional.empty
// System.out.println(add(a, b));
// System.out.println(add(a, Optional.empty()));
// System.out.println(add(Optional.empty(), b));
}
Optional<Integer> add(Optional<Integer> oa, Optional<Integer> ob) {
return oa.flatMap(a -> ob.map(b -> a + b));
}
void optionalCompute() {
Optional<Integer> a = Optional.of(13);
Optional<Integer> b = Optional.of(42);
BiFunction<Integer, Integer, Integer> plus = (x, y) -> x + y;
BiFunction<Integer, Integer, Integer> times = (x, y) -> x * y;
compute(plus, a, b); // Optional[55]
compute(times, a, b); // Optional[546]
// System.out.println(compute(plus, a, b));
// System.out.println(compute(times, a, b));
}
<A, B, R> Optional<R> compute(BiFunction<A, B, R> operation, Optional<A> oa, Optional<B> ob) {
return oa.flatMap(a -> ob.map(b -> operation.apply(a, b)));
}
void optionalStreams() {
Optional<Integer> one = Optional.of(1);
Stream<Optional<Integer>> stream = Stream.of(1, 2, 3, 4).map(Optional::of);
BiFunction<Integer, Integer, Integer> times = (x, y) -> x * y;
stream.reduce(one, (acc, elem) -> compute(times, acc, elem)); // Optional[24]
// System.out.println(stream.reduce(one, (x, y) -> compute(times, x, y)));
stream = Stream.of(Optional.of(10), Optional.empty());
stream.reduce(one, (acc, elem) -> compute(times, acc, elem)); // Optional.empty
// System.out.println(stream.reduce(one, (x, y) -> compute(times, x, y)));
}
void optionalFlatten() {
Stream<Optional<Integer>> stream = Stream.of(1, 2, 3, 4).map(Optional::of);
BiFunction<Integer, Integer, Integer> times = (x, y) -> x * y;
stream.reduce((acc, elem) -> compute(times, acc, elem)); // Optional[Optional[24]]
// System.out.println(stream.reduce((x, y) -> compute(times, x, y)));
Optional<Optional<Integer>> ooa = Optional.of(Optional.of(24));
Optional<Integer> oa = ooa.flatMap(o -> o); // Optional[24]
// System.out.println(oa);
}
}
@EqualsAndHashCode @ToString class Wrap<T> {
private final T value;
private Wrap(T value) {
this.value = value;
}
public static <T> Wrap<T> of(T value) {
return new Wrap<>(value);
}
public <R> Wrap<R> map(Function<T, R> mapper) {
return flatMap(mapper.andThen(Wrap::of));
}
// public <R> Wrap<R> map(Function<T, R> mapper) {
// return of(mapper.apply(value));
// }
public <R> Wrap<R> flatMap(Function<T, Wrap<R>> mapper) {
return mapper.apply(value);
}
}
interface Monad<T> {
Monad<T> of(T value);
<R> Monad<R> flatMap(Function<T, Monad<R>> mapper);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment