-
Notifications
You must be signed in to change notification settings - Fork 250
Adding traverse to List, Option, Either and Tuple2 #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
de6694b
d92161a
221e26f
c21ba2b
d0eb40b
50e9122
f3cab03
a4d7c05
6a683e5
a436a4e
31fbbbe
db09a08
8d48312
7cf84dd
35aae2e
b4b27be
546dc74
dc64154
19245d5
3879302
3f724a3
a5a557b
8343962
b304afa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,7 @@ | |
|
|
||
| import java.lang.ref.SoftReference; | ||
|
|
||
| import fj.data.Array; | ||
| import fj.data.List; | ||
| import fj.data.Stream; | ||
| import fj.data.Validation; | ||
| import fj.data.*; | ||
| import fj.function.Try0; | ||
|
|
||
| public abstract class P1<A> { | ||
|
|
@@ -23,11 +20,7 @@ public abstract class P1<A> { | |
| * @return A function that returns the first element of a product. | ||
| */ | ||
| public static <A> F<P1<A>, A> __1() { | ||
| return new F<P1<A>, A>() { | ||
| public A f(final P1<A> p) { | ||
| return p._1(); | ||
| } | ||
| }; | ||
| return p -> p._1(); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -37,11 +30,7 @@ public A f(final P1<A> p) { | |
| * @return A function promoted to operate on P1s. | ||
| */ | ||
| public static <A, B> F<P1<A>, P1<B>> fmap(final F<A, B> f) { | ||
| return new F<P1<A>, P1<B>>() { | ||
| public P1<B> f(final P1<A> a) { | ||
| return a.map(f); | ||
| } | ||
| }; | ||
| return a -> a.map(f); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -52,11 +41,7 @@ public P1<B> f(final P1<A> a) { | |
| */ | ||
| public <B> P1<B> bind(final F<A, P1<B>> f) { | ||
| P1<A> self = this; | ||
| return new P1<B>() { | ||
| public B _1() { | ||
| return f.f(self._1())._1(); | ||
| } | ||
| }; | ||
| return P.lazy(u -> f.f(self._1())._1()); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -66,15 +51,7 @@ public B _1() { | |
| * @return A function whose result is wrapped in a P1. | ||
| */ | ||
| public static <A, B> F<A, P1<B>> curry(final F<A, B> f) { | ||
| return new F<A, P1<B>>() { | ||
| public P1<B> f(final A a) { | ||
| return new P1<B>() { | ||
| public B _1() { | ||
| return f.f(a); | ||
| } | ||
| }; | ||
| } | ||
| }; | ||
| return a -> P.lazy(u -> f.f(a)); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -85,11 +62,7 @@ public B _1() { | |
| */ | ||
| public <B> P1<B> apply(final P1<F<A, B>> cf) { | ||
| P1<A> self = this; | ||
| return cf.bind(new F<F<A, B>, P1<B>>() { | ||
| public P1<B> f(final F<A, B> f) { | ||
| return fmap(f).f(self); | ||
| } | ||
| }); | ||
| return cf.bind(f -> fmap(f).f(self)); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -120,11 +93,7 @@ public static <A> P1<A> join(final P1<P1<A>> a) { | |
| * @return A function of arity-2 promoted to map over P1s. | ||
| */ | ||
| public static <A, B, C> F<P1<A>, F<P1<B>, P1<C>>> liftM2(final F<A, F<B, C>> f) { | ||
| return Function.curry(new F2<P1<A>, P1<B>, P1<C>>() { | ||
| public P1<C> f(final P1<A> pa, final P1<B> pb) { | ||
| return pa.bind(pb, f); | ||
| } | ||
| }); | ||
| return Function.curry((pa, pb) -> pa.bind(pb, f)); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -143,11 +112,7 @@ public static <A> P1<List<A>> sequence(final List<P1<A>> as) { | |
| * @return A function from a List of P1s to a single P1 of a List. | ||
| */ | ||
| public static <A> F<List<P1<A>>, P1<List<A>>> sequenceList() { | ||
| return new F<List<P1<A>>, P1<List<A>>>() { | ||
| public P1<List<A>> f(final List<P1<A>> as) { | ||
| return sequence(as); | ||
| } | ||
| }; | ||
| return as -> sequence(as); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -167,11 +132,57 @@ public static <A> P1<Stream<A>> sequence(final Stream<P1<A>> as) { | |
| * @return A single P1 for the given array. | ||
| */ | ||
| public static <A> P1<Array<A>> sequence(final Array<P1<A>> as) { | ||
| return new P1<Array<A>>() { | ||
| public Array<A> _1() { | ||
| return as.map(P1.<A>__1()); | ||
| } | ||
| }; | ||
| return P.lazy(u -> as.map(P1.<A>__1())); | ||
| } | ||
|
|
||
| /** | ||
| * Traversable instance of P1 for List | ||
| * | ||
| * @param f The function that takes A and produces a List<B> (non-deterministic result) | ||
| * @return A List of P1<B> | ||
| */ | ||
| public <B> List<P1<B>> traverseList(final F<A, List<B>> f){ | ||
| return f.f(_1()).map(b -> P.p(b)); | ||
| } | ||
|
|
||
| /** | ||
| * Traversable instance of P1 for Either | ||
| * | ||
| * @param f The function produces Either | ||
| * @return An Either of P1<B> | ||
| */ | ||
| public <B, X> Either<X, P1<B>> traverseEither(final F<A, Either<X, B>> f){ | ||
| return f.f(_1()).right().map(b -> P.p(b)); | ||
| } | ||
|
|
||
| /** | ||
| * Traversable instance of P1 for Option | ||
| * | ||
| * @param f The function that produces Option | ||
| * @return An Option of P1<B> | ||
| */ | ||
| public <B> Option<P1<B>> traverseOption(final F<A, Option<B>> f){ | ||
| return f.f(_1()).map(b -> P.p(b)); | ||
| } | ||
|
|
||
| /** | ||
| * Traversable instance of P1 for Validation | ||
| * | ||
| * @param f The function might produces Validation | ||
| * @return An Validation of P1<B> | ||
| */ | ||
| public <B, E> Validation<E, P1<B>> traverseValidation(final F<A, Validation<E, B>> f){ | ||
| return f.f(_1()).map(b -> P.p(b)); | ||
| } | ||
|
|
||
| /** | ||
| * Traversable instance of P1 for Stream | ||
| * | ||
| * @param f The function that produces Stream | ||
| * @return An Stream of P1<B> | ||
| */ | ||
| public <B> Stream<P1<B>> traverseStream(final F<A, Stream<B>> f){ | ||
| return f.f(_1()).map(b -> P.p(b)); | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like you have forgotten to update this for a stream. |
||
| /** | ||
|
|
@@ -182,11 +193,7 @@ public Array<A> _1() { | |
| */ | ||
| public <X> P1<X> map(final F<A, X> f) { | ||
| final P1<A> self = this; | ||
| return new P1<X>() { | ||
| public X _1() { | ||
| return f.f(self._1()); | ||
| } | ||
| }; | ||
| return P.lazy(u -> f.f(self._1())); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -195,12 +202,12 @@ public X _1() { | |
| * @return A P1 that calls this P1 once and remembers the value for subsequent calls. | ||
| */ | ||
| public P1<A> memo() { | ||
| final P1<A> self = this; | ||
| final P1<A> self = this; | ||
| return new P1<A>() { | ||
| private final Object latch = new Object(); | ||
| @SuppressWarnings({"InstanceVariableMayNotBeInitialized"}) | ||
| private volatile SoftReference<A> v; | ||
|
|
||
| public A _1() { | ||
| A a = v != null ? v.get() : null; | ||
| if (a == null) | ||
|
|
@@ -225,22 +232,19 @@ static <A> P1<A> memo(F<Unit, A> f) { | |
| */ | ||
| public <B> F<B, A> constant() { | ||
|
|
||
| return new F<B, A>() { | ||
| public A f(final B b) { | ||
| return P1.this._1(); | ||
| } | ||
| }; | ||
| return b -> P1.this._1(); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return Show.p1Show(Show.<A>anyShow()).showS(this); | ||
| } | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| @Override | ||
| public boolean equals(Object other) { | ||
| return !Equal.equalsValidationCheck(this, other) ? false : | ||
| Equal.p1Equal(Equal.<A>anyEqual()).eq(this, (P1<A>) other); | ||
| return Equal.equalsValidationCheck(this, other) | ||
| && Equal.p1Equal(Equal.<A>anyEqual()).eq(this, (P1<A>) other); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for point this out. In the future, please do this as part of a different change request. I did this change in lots of places, so this change should be applied for most of those classes implementing equals.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure @mperry . I thought that is too minor to have a separate PR. Affirmative to the point of tracking things separately. |
||
| } | ||
|
|
||
| @Override | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have copy and pasted and forgotten to change the signature to include option here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops..