Created by Mark Perry, @mprry, G+, Blog, LinkedIn, GitHub, maperry78@yahoo.com.au
![]() |
![]() |
![]() |
List.list(1, 2, 3, 4)
.map(i -> i + 10)
.filter(i -> i % 2 == 0)
.map(i -> i * 3);
// List.list(36,42)
interface F0<A> {
A f();
}
abstract class P1<A> implements F0<A> {
abstract A _1();
A f() {...}
P1<B> map(F<A, B> f) {...}
P1<B> bind(F<A, P1<B>> f) {...}
P1<A> join(P1<P1<A>> p) {...}
P1<C> liftM2(P1<B> p, F<A, B, C> f) {...}
// more methods
}
abstract class P2<A, B> {
abstract A _1();
abstract B _2();
// more methods
}
public static P1<A> p(A a) {
return new P1<A>() {
A _1() {
return a;
}
};
}
P1<Integer> p1 = P.p(1);
public static P1<A> lazy(F0<A> f) {
return new P1<A>() {
A _1() {
return f.f();
}
};
}
P1<Integer> p2 = P.lazy(() -> intFunction());
static boolean or(boolean b, F0<Boolean> f) {
return b ? true : f.f();
}
or(true, () -> false);
or(true, () -> expensiveMethod());
static boolean and(boolean b, F0<Boolean> f) {
return b ? f.f() : false;
}
and(false, () -> expensiveMethod());
static A if2(boolean b, F0<A> onTrue, F0<A> onFalse) {
return b ? onTrue.f() : onFalse.f();
}
if2(false, () -> expensiveMethod(), () -> 3);
P1<Integer> p = P.lazy(() -> factorial(100)).memo();
int a = p._1(); // very slow
int b = p._1(); // return calculated value
abstract class Stream<A> {
abstract A head();
P1<Stream<A>> tail();
static Stream<A> stream(A... as) { ... }
static Stream<A> cons(A head, F0<Stream<A>> tail) { ... }
<B> Stream<B> map(F<A, B> f) { ... }
Stream<A> filter(F<A, Boolean> f) { ... }
<B> B fold(F2<B, A, B> f, B b) { ... }
<B> Stream<B> bind(F<A, Stream<B>> f) { ... }
}
static <A> List<A> toList(Stream<A> s);
static <A> Stream<A> take(Stream<A> s, int n);
static <A> Stream<A> takeWhile(Stream<A> s, F<A, Boolean> f);
static <A> boolean exists(Stream<A> s, F<A, Boolean>) {
if (s.isEmpty()) {
return false;
} else {
return f.f(s.head()) ? true : exists(s.tail()._1(), f);
}
}
static <A, B> B foldRight(Stream<A> s, F0<B> acc, F2<F0<B>, A, B> f) {
if (s.isEmpty()) {
return acc.f();
} else {
return f.f(() -> foldRight(s.tail()._1(), acc, f), s.head());
}
}
static <A> boolean exists(Stream<A> s, F<A, Boolean> f) {
return foldRight(s, () -> false, (lb, a) -> f.f(a) || lb.f());
}
F<Integer, Integer> add = i -> i + 10;
F<Integer, Boolean> even = i -> i % 2 == 0;
stream(1, 2, 3, 4).map(add).filter(even).toList();
Stream.cons(11, stream(2, 3, 4).map(add)).filter(even).toList();
Stream.stream(2, 3, 4).map(add).filter(even).toList();
Stream.cons(12, stream(3, 4).map(add)).filter(even).toList();
List.cons(12, stream(3, 4).map(add).filter(even)).toList();
List.cons(12, Stream.cons(13, stream(4).map(add)).filter(even).toList());
List.cons(12, stream(4).map(add).filter(even).toList());
List.cons(12, Stream.cons(14, Stream.nil().map(add)).filter(even).toList());
List.cons(12, List.cons(14, Stream.nil().map(add).filter(even).toList()));
List.cons(12, List.cons(14, List.nil());
Stream<Integer> s1 = Stream.range(1); // [1, 2, 3, ...]
List<Integer> list = s1.take(5).toList()
Stream<String> s2 = Stream.repeat("a"); // ["a", "a", "a", ...]
Write
// assuming existence of cons
static <A> Stream<A> cons(A head, F0<Stream<A>> tail);
static <A> Stream<A> repeat(A a);
static Stream<Integer> from(int i);
static Stream<Integer> range(int low, int high); // [low, high)
static Stream<Integer> fibonacci(int a, int b);
static Stream<A> unfold(S s, F<S, Option<P2<A, S>>> f);
![]() |
![]() |
![]() |
Created by Mark Perry, @mprry, G+, Blog, LinkedIn, GitHub, maperry78@yahoo.com.au