Skip to content

Commit efd0bfb

Browse files
committed
Merge branch 'master' into pqueue
2 parents 1a7f3e6 + 34534a8 commit efd0bfb

36 files changed

Lines changed: 2473 additions & 1897 deletions

core/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ archivesBaseName = project.projectName
77

88
dependencies {
99
testCompile dependencyJunit
10+
testCompile 'com.h2database:h2:1.4.191'
11+
testCompile 'commons-dbutils:commons-dbutils:1.6'
1012
}
1113

1214
performSigning(signingEnabled, signModule)

core/src/main/java/fj/Equal.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public F2<A, A, Boolean> eq() {
6565
* @return A function that returns <code>true</code> if the given argument equals the argument to this method.
6666
*/
6767
public F<A, Boolean> eq(final A a) {
68-
return a1 -> eq(a, a1);
68+
return f.f(a);
6969
}
7070

7171
/**
@@ -149,6 +149,11 @@ public static <A> Equal<A> anyEqual() {
149149
*/
150150
public static final Equal<Short> shortEqual = anyEqual();
151151

152+
/**
153+
* An equal instance for the <code>Natural</code> type.
154+
*/
155+
public static final Equal<Natural> naturalEqual = bigintEqual.contramap(Natural::bigIntegerValue);
156+
152157
/**
153158
* An equal instance for the {@link String} type.
154159
*/

core/src/main/java/fj/Hash.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ public static <A> Hash<A> anyHash() {
115115
*/
116116
public static final Hash<BigDecimal> bigdecimalHash = anyHash();
117117

118+
/**
119+
* A hash instance for the {@link Natural} type.
120+
*/
121+
public static final Hash<Natural> naturalHash = bigintHash.contramap(Natural::bigIntegerValue);
122+
118123
/**
119124
* A hash instance for the <code>String</code> type.
120125
*/
@@ -535,4 +540,5 @@ public static <A> Hash<V7<A>> v7Hash(final Hash<A> ea) {
535540
public static <A> Hash<V8<A>> v8Hash(final Hash<A> ea) {
536541
return streamHash(ea).contramap(V8.toStream_());
537542
}
543+
538544
}

core/src/main/java/fj/P2.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ public static <A, B, C> PLens<P2<A, B>, P2<C, B>, A, C> _1p() {
335335
/**
336336
* Monomorphic lens targeted on _1.
337337
*/
338-
public static <A, B, C> Lens<P2<A, B>, A> _1() {
338+
public static <A, B> Lens<P2<A, B>, A> _1() {
339339
return new Lens<>(_1p());
340340
}
341341

@@ -349,7 +349,7 @@ public static <A, B, C> PLens<P2<A, B>, P2<A, C>, B, C> _2p() {
349349
/**
350350
* Monomorphic lens targeted on _1.
351351
*/
352-
public static <A, B, C> Lens<P2<A, B>, B> _2() {
352+
public static <A, B> Lens<P2<A, B>, B> _2() {
353353
return new Lens<>(_2p());
354354
}
355355

core/src/main/java/fj/Semigroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
219219
semigroup(Natural::multiply);
220220

221221
/**
222-
* A semigroup that multiplies natural numbers.
222+
* A semigroup that adds natural numbers.
223223
*/
224224
public static final Semigroup<Natural> naturalAdditionSemigroup =
225225
semigroup(Natural::add);

core/src/main/java/fj/control/db/DB.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import fj.F;
44
import fj.Function;
5+
import fj.function.Try1;
56

67
import java.sql.Connection;
78
import java.sql.SQLException;
@@ -35,6 +36,21 @@ public A run(final Connection c) {
3536
};
3637
}
3738

39+
/**
40+
* Constructs a database action as a function from a database connection to a value.
41+
*
42+
* @param t A function from a database connection to a value allowed to throw
43+
* SQLException
44+
* @return A database action representing the given function.
45+
*/
46+
public static <A> DB<A> db(final Try1<Connection, A, SQLException> t){
47+
return new DB<A>() {
48+
public A run(final Connection c) throws SQLException {
49+
return t.f(c);
50+
}
51+
};
52+
}
53+
3854
/**
3955
* Returns the callable-valued function projection of this database action.
4056
*

core/src/main/java/fj/data/Array.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,9 @@ public Object[] array() {
135135
* affectation of the result of this method to a non generic array
136136
* will result in runtime error (ClassCastException).
137137
*
138-
* @deprecated use {@link #array(Class)}
138+
* @deprecated As of release 4.6, use {@link #array(Class)}.
139139
*/
140+
@SuppressWarnings("unchecked")
140141
@Deprecated
141142
public A[] toJavaArray() {
142143
return (A[]) array();

core/src/main/java/fj/data/List.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,9 @@ public final Object[] toArrayObject() {
216216
* affectation of the result of this method to a non generic array
217217
* will result in runtime error (ClassCastException).
218218
*
219-
* @deprecated use {@link #array(Class)}
219+
* @deprecated As of release 4.6, use {@link #array(Class)}.
220220
*/
221+
@SuppressWarnings("unchecked")
221222
@Deprecated
222223
public final A[] toJavaArray() {
223224
return (A[]) toArrayObject();

core/src/main/java/fj/data/Natural.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package fj.data;
22

33
import static fj.Bottom.error;
4+
5+
import fj.Equal;
46
import fj.F;
57

68
import static fj.Monoid.naturalAdditionMonoid;
79
import static fj.Monoid.naturalMultiplicationMonoid;
810
import static fj.Function.curry;
11+
12+
import fj.Hash;
13+
import fj.Show;
914
import fj.data.vector.V2;
1015
import fj.data.vector.V;
1116

@@ -121,7 +126,7 @@ public Natural add(final Natural n) {
121126
* @return The difference between the two numbers, if this number is larger than the given one. Otherwise none.
122127
*/
123128
public Option<Natural> subtract(final Natural n) {
124-
return natural(n.value.subtract(value));
129+
return natural(value.subtract(n.value));
125130
}
126131

127132
/**
@@ -286,4 +291,20 @@ public static Natural sum(final List<Natural> ns) {
286291
public static Natural product(final List<Natural> ns) {
287292
return naturalMultiplicationMonoid.sumLeft(ns);
288293
}
294+
295+
296+
@Override
297+
public int hashCode() {
298+
return Hash.naturalHash.hash(this);
299+
}
300+
301+
@Override
302+
public boolean equals(final Object that) {
303+
return Equal.equals0(Natural.class, this, that, Equal.naturalEqual);
304+
}
305+
306+
@Override
307+
public String toString() {
308+
return Show.naturalShow.showS(this);
309+
}
289310
}
Lines changed: 107 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,119 @@
11
package fj.data;
22

3-
import fj.*;
3+
import fj.F;
4+
import fj.P2;
5+
import fj.Unit;
6+
import fj.control.Trampoline;
47

8+
import static fj.P.lazy;
59
import static fj.P.p;
10+
import static fj.control.Trampoline.suspend;
11+
import static fj.data.List.cons;
612

713
/**
814
* Created by MarkPerry on 7/07/2014.
915
*/
1016
public final class State<S, A> {
1117

12-
private final F<S, P2<S, A>> run;
13-
14-
private State(F<S, P2<S, A>> f) {
15-
run = f;
16-
}
17-
18-
public P2<S, A> run(S s) {
19-
return run.f(s);
20-
}
21-
22-
public static <S, A> State<S, A> unit(F<S, P2<S, A>> f) {
23-
return new State<>(f);
24-
}
25-
26-
public static <S> State<S, S> units(F<S, S> f) {
27-
return unit((S s) -> {
28-
S s2 = f.f(s);
29-
return p(s2, s2);
30-
});
31-
}
32-
33-
public static <S, A> State<S, A> constant(A a) {
34-
return unit(s -> p(s, a));
35-
}
36-
37-
public <B> State<S, B> map(F<A, B> f) {
38-
return unit((S s) -> {
39-
P2<S, A> p2 = run(s);
40-
B b = f.f(p2._2());
41-
return p(p2._1(), b);
42-
});
43-
}
44-
45-
public static <S> State<S, Unit> modify(F<S, S> f) {
46-
return State.<S>init().flatMap(s -> unit(s2 -> p(f.f(s), Unit.unit())));
47-
}
48-
49-
public <B> State<S, B> mapState(F<P2<S, A>, P2<S, B>> f) {
50-
return unit(s -> f.f(run(s)));
51-
}
52-
53-
public static <S, B, C> State<S, C> flatMap(State<S, B> mb, F<B, State<S, C>> f) {
54-
return mb.flatMap(f);
55-
}
56-
57-
public <B> State<S, B> flatMap(F<A, State<S, B>> f) {
58-
return unit((S s) -> {
59-
P2<S, A> p = run(s);
60-
A a = p._2();
61-
S s2 = p._1();
62-
State<S, B> smb = f.f(a);
63-
return smb.run(s2);
64-
});
65-
}
66-
67-
public static <S> State<S, S> init() {
68-
return unit(s -> p(s, s));
69-
}
70-
71-
public State<S, S> gets() {
72-
return unit(s -> {
73-
P2<S, A> p = run(s);
74-
S s2 = p._1();
75-
return p(s2, s2);
76-
});
77-
}
78-
79-
public static <S> State<S, Unit> put(S s) {
80-
return unit((S z) -> p(s, Unit.unit()));
81-
}
82-
83-
public A eval(S s) {
84-
return run(s)._2();
85-
}
86-
87-
public S exec(S s) {
88-
return run(s)._1();
89-
}
90-
91-
public State<S, A> withs(F<S, S> f) {
92-
return unit(F1Functions.andThen(f, run));
93-
}
94-
95-
public static <S, A> State<S, A> gets(F<S, A> f) {
96-
return State.<S>init().map(f);
97-
}
98-
99-
/**
100-
* Evaluate each action in the sequence from left to right, and collect the results.
101-
*/
102-
public static <S, A> State<S, List<A>> sequence(List<State<S, A>> list) {
103-
return list.foldLeft((State<S, List<A>> acc, State<S, A> ma) ->
104-
acc.flatMap((List<A> xs) -> ma.map(xs::snoc)
105-
), constant(List.nil()));
106-
}
107-
108-
/**
109-
* Map each element of a structure to an action, evaluate these actions from left to right
110-
* and collect the results.
111-
*/
112-
public static <S, A, B> State<S, List<B>> traverse(List<A> list, F<A, State<S, B>> f) {
113-
return list.foldLeft((State<S, List<B>> acc, A a) ->
114-
acc.flatMap(bs -> f.f(a).map(bs::snoc)
115-
), constant(List.nil()));
116-
}
18+
public static <S, A> State<S, A> unit(F<S, P2<S, A>> runF) {
19+
return new State<>(s -> Trampoline.pure(runF.f(s)));
20+
}
21+
22+
public static <S> State<S, S> init() {
23+
return unit(s -> dup(s));
24+
}
25+
26+
public static <S> State<S, S> units(F<S, S> f) {
27+
return unit(s -> dup(f.f(s)));
28+
}
29+
30+
private static <S> P2<S, S> dup(S s) {
31+
return p(s, s);
32+
}
33+
34+
public static <S, A> State<S, A> constant(A a) {
35+
return unit(s -> p(s, a));
36+
}
37+
38+
public static <S, A> State<S, A> gets(F<S, A> f) {
39+
return unit(s -> p(s, f.f(s)));
40+
}
41+
42+
public static <S> State<S, Unit> put(S s) {
43+
return unit(ignoredS -> p(s, Unit.unit()));
44+
}
45+
46+
public static <S> State<S, Unit> modify(F<S, S> f) {
47+
return unit(s -> p(f.f(s), Unit.unit()));
48+
}
49+
50+
public static <S, A, B> State<S, B> flatMap(State<S, A> ts, F<A, State<S, B>> f) {
51+
return ts.flatMap(f);
52+
}
53+
54+
/**
55+
* Evaluate each action in the sequence from left to right, and collect the results.
56+
*/
57+
public static <S, A> State<S, List<A>> sequence(List<State<S, A>> list) {
58+
return list
59+
.foldLeft(
60+
(acc, ts) -> acc.flatMap(as -> ts.map(a -> cons(a, as))),
61+
State.<S, List<A>>constant(List.nil()))
62+
.map(as -> as.reverse());
63+
}
64+
65+
/**
66+
* Map each element of a structure to an action, evaluate these actions from left to right
67+
* and collect the results.
68+
*/
69+
public static <S, A, B> State<S, List<B>> traverse(List<A> list, F<A, State<S, B>> f) {
70+
return list
71+
.foldLeft(
72+
(acc, a) -> acc.flatMap(bs -> f.f(a).map(b -> cons(b, bs))),
73+
State.<S, List<B>>constant(List.nil()))
74+
.map(bs -> bs.reverse());
75+
}
76+
77+
private static <S, A> State<S, A> suspended(F<S, Trampoline<P2<S, A>>> runF) {
78+
return new State<>(s -> suspend(lazy(() -> runF.f(s))));
79+
}
80+
81+
private final F<S, Trampoline<P2<S, A>>> runF;
82+
83+
private State(F<S, Trampoline<P2<S, A>>> runF) {
84+
this.runF = runF;
85+
}
86+
87+
public P2<S, A> run(S s) {
88+
return runF.f(s).run();
89+
}
90+
91+
public A eval(S s) {
92+
return run(s)._2();
93+
}
94+
95+
public S exec(S s) {
96+
return run(s)._1();
97+
}
98+
99+
public State<S, S> gets() {
100+
return mapState(result -> p(result._1(), result._1()));
101+
}
102+
103+
public <B> State<S, B> map(F<A, B> f) {
104+
return mapState(result -> p(result._1(), f.f(result._2())));
105+
}
106+
107+
public <B> State<S, B> mapState(F<P2<S, A>, P2<S, B>> f) {
108+
return suspended(s -> runF.f(s).map(result -> f.f(result)));
109+
}
110+
111+
public State<S, A> withs(F<S, S> f) {
112+
return suspended(s -> runF.f(f.f(s)));
113+
}
114+
115+
public <B> State<S, B> flatMap(F<A, State<S, B>> f) {
116+
return suspended(s -> runF.f(s).bind(result -> Trampoline.pure(f.f(result._2()).run(result._1()))));
117+
}
117118

118119
}

0 commit comments

Comments
 (0)