Skip to content

Commit dec583c

Browse files
committed
DList
1 parent 071190f commit dec583c

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ build
1414
MANIFEST.MF
1515
*/bin/**
1616
*~
17+
/.nb-gradle/
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package fj.data;
2+
3+
import fj.F;
4+
import fj.P;
5+
import fj.control.Trampoline;
6+
7+
/**
8+
* Difference List. It converts left associative appends into right associative ones to improve performance.
9+
*
10+
* @version %build.number%
11+
*/
12+
public class DList<A> {
13+
private final F<List<A>,Trampoline<List<A>>> appendFn;
14+
15+
private DList(F<List<A>,Trampoline<List<A>>> appendFn) {
16+
this.appendFn = appendFn;
17+
}
18+
19+
public static <A> DList<A> fromList(List<A> a) {
20+
return new DList<>((List<A> tail) -> Trampoline.pure(a.append(tail)));
21+
}
22+
23+
public List<A> run() {
24+
return appendFn.f(List.<A>nil()).run();
25+
}
26+
27+
public static <A> DList<A> nil() {
28+
return new DList<>(Trampoline.<List<A>>pure());
29+
}
30+
31+
public static <A> DList<A> single(A a) {
32+
return new DList<>((List<A> tail) -> Trampoline.pure(tail.cons(a)));
33+
}
34+
35+
public DList<A> cons(A a) {
36+
return DList.single(a).append(this);
37+
}
38+
39+
public DList<A> snoc(A a) {
40+
return this.append(DList.single(a));
41+
}
42+
43+
public DList<A> append(DList<A> other) {
44+
return new DList<>(kleisliTrampCompose(this.appendFn, other.appendFn));
45+
}
46+
47+
private static <A,B,C> F<A,Trampoline<C>> kleisliTrampCompose(F<B,Trampoline<C>> bc, F<A,Trampoline<B>> ab) {
48+
return (A a) -> ab.f(a).bind((B b) -> Trampoline.suspend(P.lazy(() -> bc.f(b))));
49+
}
50+
}

0 commit comments

Comments
 (0)