annotate src/main/java/fj/data/Seq.java @ 1:8ed7d71e8617

minner change
author tatsuki
date Sat, 21 Mar 2015 05:32:16 +0900
parents fe80c1edf1be
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
1 package fj.data;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
2
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
3 import fj.F;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
4 import fj.F2;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
5 import fj.Function;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
6 import static fj.Bottom.error;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
7 import static fj.Monoid.intAdditionMonoid;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
8 import static fj.data.fingertrees.FingerTree.measured;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
9
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
10 import fj.data.fingertrees.FingerTree;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
11 import fj.data.fingertrees.MakeTree;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
12 import fj.data.fingertrees.Measured;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
13
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
14 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
15 * Provides an immutable finite sequence, implemented as a finger tree. This structure gives O(1) access to
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
16 * the head and tail, as well as O(log n) random access and concatenation of sequences.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
17 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
18 public final class Seq<A> {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
19 private static final Measured<Integer, Object> ELEM_MEASURED = measured(intAdditionMonoid, Function.constant(1));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
20 private static final MakeTree<Integer, Object> MK_TREE = FingerTree.mkTree(ELEM_MEASURED);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
21 private static final Seq<Object> EMPTY = new Seq<Object>(MK_TREE.empty());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
22
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
23 @SuppressWarnings("unchecked")
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
24 private static <A> MakeTree<Integer, A> mkTree() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
25 return (MakeTree<Integer, A>) MK_TREE;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
26 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
27
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
28 private final FingerTree<Integer, A> ftree;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
29
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
30 private Seq(final FingerTree<Integer, A> ftree) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
31 this.ftree = ftree;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
32 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
33
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
34 @SuppressWarnings("unchecked")
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
35 private static <A> Measured<Integer, A> elemMeasured() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
36 return (Measured<Integer, A>) ELEM_MEASURED;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
37 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
38
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
39 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
40 * The empty sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
41 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
42 * @return A sequence with no elements.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
43 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
44 @SuppressWarnings("unchecked")
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
45 public static <A> Seq<A> empty() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
46 return (Seq<A>) EMPTY;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
47 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
48
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
49 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
50 * A singleton sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
51 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
52 * @param a The single element in the sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
53 * @return A new sequence with the given element in it.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
54 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
55 public static <A> Seq<A> single(final A a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
56 return new Seq<A>(Seq.<A>mkTree().single(a));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
57 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
58
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
59 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
60 * Inserts the given element at the front of this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
61 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
62 * @param a An element to insert at the front of this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
63 * @return A new sequence with the given element at the front.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
64 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
65 public Seq<A> cons(final A a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
66 return new Seq<A>(ftree.cons(a));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
67 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
68
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
69 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
70 * Inserts the given element at the end of this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
71 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
72 * @param a An element to insert at the end of this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
73 * @return A new sequence with the given element at the end.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
74 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
75 public Seq<A> snoc(final A a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
76 return new Seq<A>(ftree.snoc(a));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
77 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
78
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
79 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
80 * Appends the given sequence to this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
81 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
82 * @param as A sequence to append to this one.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
83 * @return A new sequence with the given sequence appended to this one.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
84 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
85 public Seq<A> append(final Seq<A> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
86 return new Seq<A>(ftree.append(as.ftree));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
87 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
88
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
89 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
90 * Checks if this is the empty sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
91 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
92 * @return True if this sequence is empty, otherwise false.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
93 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
94 public boolean isEmpty() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
95 return ftree.isEmpty();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
96 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
97
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
98 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
99 * Returns the number of elements in this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
100 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
101 * @return the number of elements in this sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
102 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
103 public int length() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
104 return ftree.measure();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
105 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
106
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
107 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
108 * Returns the element at the given index.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
109 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
110 * @param i The index of the element to return.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
111 * @return The element at the given index, or throws an error if the index is out of bounds.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
112 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
113 public A index(final int i) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
114 if (i < 0 || i >= length())
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
115 throw error("Index " + i + "out of bounds.");
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
116 return ftree.lookup(Function.<Integer>identity(), i)._2();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
117 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
118
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
119 public <B> B foldLeft(final F2<B, A, B> f, final B z) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
120 return ftree.foldLeft(f, z);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
121 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
122
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
123 public <B> B foldRight(final F2<A, B, B> f, final B z) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
124 return ftree.foldRight(f, z);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
125 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
126
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
127 public <B> Seq<B> map(F<A, B> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
128 return new Seq<B>(ftree.map(f, Seq.<B>elemMeasured()));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
129 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
130
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
131 }