Last active
May 8, 2017 15:37
-
-
Save juanmc2005/4c5938d1e454c9d20b37320e0b7c29d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Action { | |
void run(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface BiFunction<A, B, C> { | |
C apply(A x, B y); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Consumer<T> { | |
void apply(T x); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Either<L, R> { | |
public static <L, R> Either<L, R> left(L value) { | |
return new Either<>(Option.just(value), Option.none()); | |
} | |
public static <L, R> Either<L, R> right(R value) { | |
return new Either<>(Option.none(), Option.just(value)); | |
} | |
private final Option<L> valueLeft; | |
private final Option<R> valueRight; | |
private Either(Option<L> valueLeft, Option<R> valueRight) { | |
this.valueLeft = valueLeft; | |
this.valueRight = valueRight; | |
} | |
public boolean isLeft() { | |
return valueLeft.isPresent(); | |
} | |
public boolean isRight() { | |
return valueRight.isPresent(); | |
} | |
public <T> Either<T, R> mapLeft(Function<L, T> f) { | |
if (isLeft()) return left(f.apply(valueLeft.get())); | |
else return right(valueRight.get()); | |
} | |
public <T> Either<L, T> mapRight(Function<R, T> f) { | |
if (isRight()) return right(f.apply(valueRight.get())); | |
else return left(valueLeft.get()); | |
} | |
public <T> Option<T> flatMapOption(Function<L, T> f1, Function<R, T> f2) { | |
if (isLeft()) return Option.just(f1.apply(valueLeft.get())); | |
else return Option.just(f2.apply(valueRight.get())); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Function<T, R> { | |
R apply(T x); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final class Lists { | |
private Lists() { | |
throw new IllegalAccessError("Cannot instantiate Lists"); | |
} | |
public static <A, B> List<B> map(final List<A> xs, final Function<A, B> f) { | |
final List<B> result = new ArrayList<>(); | |
for (A a : xs) result.add(f.apply(a)); | |
return result; | |
} | |
public static <A> List<A> filter(final List<A> xs, final Function<A, Boolean> f) { | |
final List<A> result = new ArrayList<>(); | |
for (A a : xs) if (f.apply(a)) result.add(a); | |
return result; | |
} | |
public static <A> List<A> flatten(final List<List<A>> xss) { | |
final List<A> result = new ArrayList<>(); | |
for (List<A> xs : xss) for (A x : xs) result.add(x); | |
return result; | |
} | |
public static <A, B> List<B> flatMap(final List<A> xs, final Function<A, List<B>> f) { | |
return flatten(map(xs, f)); | |
} | |
public static <A, B> B fold(final B acc, final List<A> xs, final BiFunction<A, B, B> f) { | |
B result = acc; | |
for (A x : xs) result = f.apply(x, result); | |
return result; | |
} | |
public static <A, B> B interruptedFold(final B acc, List<A> xs, final BiFunction<A, B, Pair<Boolean, B>> f) { | |
B result = acc; | |
for (A x : xs) { | |
Pair<Boolean, B> pair = f.apply(x, result); | |
result = pair.second; | |
if (!pair.first) return result; | |
} | |
return result; | |
} | |
public static <A> Option<A> find(final List<A> xs, final Function<A, Boolean> f) { | |
return interruptedFold(Option.none(), xs, (x, opt) -> | |
f.apply(x) | |
? new Pair<>(false, Option.just(x)) | |
: new Pair<>(true, Option.none())); | |
} | |
public static <A> List<A> cons(final A x, final List<A> xs) { | |
xs.add(0, x); | |
return xs; | |
} | |
public static <A> Pair<List<A>, List<A>> split(final List<A> xs, final Function<A, Boolean> f) { | |
final List<A> first = new ArrayList<>(); | |
final List<A> second = new ArrayList<>(); | |
for (A x : xs) (f.apply(x) ? first : second).add(x); | |
return new Pair<>(first, second); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Option<T> { | |
public static <A> Option<A> just(A a) { | |
return new Option<>(a); | |
} | |
public static <A> Option<A> none() { | |
return Option.just(null); | |
} | |
private final T value; | |
private Option(T value) { | |
this.value = value; | |
} | |
public T get() { | |
if (value != null) return value; | |
else throw new IllegalStateException("Cannot call get() on None"); | |
} | |
public T getOrElse(T something) { | |
if (isPresent()) return value; | |
else return something; | |
} | |
public Option<T> doIfPresent(Consumer<T> consumer) { | |
if (isPresent()) consumer.apply(value); | |
return this; | |
} | |
public Option<T> doIfNotPresent(Action action) { | |
if (!isPresent()) action.run(); | |
return this; | |
} | |
public Option<T> doIfElse(Consumer<T> consumer, Action action) { | |
if (isPresent()) consumer.apply(value); | |
else action.run(); | |
return this; | |
} | |
public <A> Option<A> mapIfElse(Function<T, A> f, Producer<A> g) { | |
if (isPresent()) return new Option<>(f.apply(value)); | |
else return Option.just(g.produce()); | |
} | |
public boolean isPresent() { | |
return value != null; | |
} | |
public <A> Option<A> map(Function<T, A> f) { | |
if (isPresent()) return Option.just(f.apply(value)); | |
else return Option.none(); | |
} | |
public Option<T> filter(Function<T, Boolean> f) { | |
if (isPresent() && f.apply(value)) return Option.just(value); | |
else return Option.none(); | |
} | |
public <A> Option<A> flatMap(Function<T, Option<A>> f) { | |
final Option<A> option = f.apply(value); | |
if (option.isPresent()) return Option.just(option.get()); | |
else return Option.none(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Producer<T> { | |
T produce(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment