Skip to content

Commit

Permalink
FJ migration
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmcclean committed Aug 8, 2017
1 parent 0734180 commit 2200285
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,34 @@
*/
@UtilityClass
public class Options {

public static <L, T, R> Option<R> tailRec(T initial, Function<? super T, ? extends Option<? extends Either<T, R>>> fn) {
Option<? extends Either<T, R>> next[] = new Option[1];
next[0] = Option.some(Either.left(initial));
boolean cont = true;
do {
cont = next[0].map(p -> p.either(s -> {
next[0] = fn.apply(s);
return true;
}, pr -> false)).orSome(false);
} while (cont);
return next[0].map(e -> e.right()
.iterator()
.next());
}
public static <T, R> Option< R> tailRecXor(T initial, Function<? super T, ? extends Option<? extends Xor<T, R>>> fn) {
Option<? extends Xor<T, R>> next[] = new Option[1];
next[0] = Option.some(Xor.secondary(initial));
boolean cont = true;
do {
cont = next[0].map(p -> p.visit(s -> {
next[0] = fn.apply(s);
return true;
}, pr -> false)).orSome(false);
} while (cont);
return next[0].map(Xor::get);
}

public static <W1,T> Coproduct<W1,option,T> coproduct(Option<T> type, InstanceDefinitions<W1> def1){
return Coproduct.of(Xor.primary(widen(type)),def1, Instances.definitions());
}
Expand Down Expand Up @@ -660,19 +688,24 @@ public <T> Maybe<MonadPlus<option>> monadPlus() {
return Maybe.just(Instances.monadPlus());
}

@Override
public <T> MonadRec<option> monadRec() {
return Instances.monadRec();
}

@Override
public <T> Maybe<MonadPlus<option>> monadPlus(Monoid<Higher<option, T>> m) {
return Maybe.just(Instances.monadPlus(m));
}

@Override
public <C2, T> Maybe<Traverse<option>> traverse() {
return Maybe.just(Instances.traverse());
public <C2, T> Traverse<option> traverse() {
return Instances.traverse();
}

@Override
public <T> Maybe<Foldable<option>> foldable() {
return Maybe.just(Instances.foldable());
public <T> Foldable<option> foldable() {
return Instances.foldable();
}

@Override
Expand Down Expand Up @@ -850,6 +883,14 @@ public static <T> MonadPlus<option> monadPlus(){
Monoid<Higher<option,T>> m2= (Monoid)m;
return General.monadPlus(monadZero(),m2);
}
public static <T> MonadRec<option> monadRec(){
return new MonadRec<option>() {
@Override
public <T, R> Higher<option, R> tailRec(T initial, Function<? super T, ? extends Higher<option, ? extends Xor<T, R>>> fn) {
return widen(Options.tailRecXor(initial,fn.andThen(OptionKind::narrow)));
}
};
}
/**
*
* <pre>
Expand Down Expand Up @@ -899,9 +940,24 @@ public static <C2,T> Traverse<option> traverse(){
* @return Type class for folding / reduction operations
*/
public static <T> Foldable<option> foldable(){
BiFunction<Monoid<T>,Higher<option,T>,T> foldRightFn = (m, l)-> OptionKind.narrow(l).orSome(m.zero());
BiFunction<Monoid<T>,Higher<option,T>,T> foldLeftFn = (m, l)-> OptionKind.narrow(l).orSome(m.zero());
return General.foldable(foldRightFn, foldLeftFn);
return new Foldable<option>() {
@Override
public <T> T foldRight(Monoid<T> m, Higher<option, T> ds) {
return OptionKind.narrow(ds).orSome(m.zero());
}

@Override
public <T> T foldLeft(Monoid<T> m, Higher<option, T> ds) {
return OptionKind.narrow(ds).orSome(m.zero());
}

@Override
public <T, R> R foldMap(Monoid<R> m, Function<? super T, ? extends R> fn, Higher<option, T> ds) {
Option<R> o = OptionKind.narrow(ds).map(a -> fn.apply(a));
return o.orSome(m.zero());
}
};

}
public static <T> Comonad<option> comonad(){
Function<? super Higher<option, T>, ? extends T> extractFn = maybe -> maybe.convert(OptionKind::narrow).some();
Expand Down Expand Up @@ -994,10 +1050,10 @@ public static <S, P> Nested<option,Higher<xor,S>, P> xor(Option<Xor<S, P>> neste
OptionKind<Higher<Higher<xor,S>, P>> y = (OptionKind)x;
return Nested.of(y,Instances.definitions(),Xor.Instances.definitions());
}
public static <S,T> Nested<option,Higher<reader,S>, T> reader(Option<Reader<S, T>> nested){
public static <S,T> Nested<option,Higher<reader,S>, T> reader(Option<Reader<S, T>> nested, S defaultValue){
OptionKind<Reader<S, T>> x = widen(nested);
OptionKind<Higher<Higher<reader,S>, T>> y = (OptionKind)x;
return Nested.of(y,Instances.definitions(),Reader.Instances.definitions());
return Nested.of(y,Instances.definitions(),Reader.Instances.definitions(defaultValue));
}
public static <S extends Throwable, P> Nested<option,Higher<Witness.tryType,S>, P> cyclopsTry(Option<cyclops.control.Try<P, S>> nested){
OptionKind<cyclops.control.Try<P, S>> x = widen(nested);
Expand Down Expand Up @@ -1052,11 +1108,11 @@ public static <S, P> Nested<Higher<xor,S>,option, P> xor(Xor<S, Option<P>> neste

return Nested.of(x,Xor.Instances.definitions(),Instances.definitions());
}
public static <S,T> Nested<Higher<reader,S>,option, T> reader(Reader<S, Option<T>> nested){
public static <S,T> Nested<Higher<reader,S>,option, T> reader(Reader<S, Option<T>> nested,S defaultValue){

Reader<S, Higher<option, T>> x = nested.map(OptionKind::widenK);

return Nested.of(x,Reader.Instances.definitions(),Instances.definitions());
return Nested.of(x,Reader.Instances.definitions(defaultValue),Instances.definitions());
}
public static <S extends Throwable, P> Nested<Higher<Witness.tryType,S>,option, P> cyclopsTry(cyclops.control.Try<Option<P>, S> nested){
cyclops.control.Try<Higher<option,P>, S> x = nested.map(OptionKind::widenK);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,59 @@ public static <W1 extends WitnessType<W1>,T> XorM<W1,stream,T> xorM(Stream<T> t
public static <T> AnyMSeq<stream,T> anyM(Stream<T> option) {
return AnyM.ofSeq(option, stream.INSTANCE);
}
public static <T,R> Stream<R> tailRec(T initial, Function<? super T, ? extends Stream<? extends Either<T, R>>> fn) {
Stream<Either<T, R>> next = Stream.stream(Either.left(initial));

boolean newValue[] = {true};
for(;;){

next = next.bind(e -> e.either(s -> {
newValue[0]=true;
return (Stream<Either<T,R>>)fn.apply(s); },
p -> {
newValue[0]=false;
return Stream.stream(e);
}));
if(!newValue[0])
break;

}

return next.filter(Either::isRight).map(e->e.right()
.iterator()
.next());
}
public static <T,R> Stream<R> tailRecXor(T initial, Function<? super T, ? extends Stream<? extends Xor<T, R>>> fn) {
Stream<Xor<T, R>> next = Stream.arrayStream(Xor.secondary(initial));

boolean newValue[] = {true};
for(;;){

next = next.bind(e -> e.visit(s -> {
newValue[0]=true;
return (Stream<Xor<T,R>>)fn.apply(s); },
p -> {
newValue[0]=false;
return Stream.arrayStream(e);
}));
if(!newValue[0])
break;

}

return next.filter(Xor::isPrimary).map(Xor::get);
}

public static <T,R> R foldRight(Stream<T> stream,R identity, BiFunction<? super T, ? super R, ? extends R> fn){
return foldRightRec(stream,Eval.now(identity),(a,b)-> b.map(b2->fn.apply(a,b2))).get();
}
private static <T,R> Eval<R> foldRightRec(Stream<T> stream,Eval<R> identity, BiFunction<? super T, ? super Eval<R>, ? extends Eval<R>> fn){

if(stream.isEmpty())
return identity;
else
return identity.flatMap(i-> fn.apply(stream.head(), foldRightRec(stream.tail()._1(), identity, fn)));
}
/**
* Perform a For Comprehension over a Stream, accepting 3 generating functions.
* This results in a four level nested internal iteration over the provided Publishers.
Expand Down Expand Up @@ -377,19 +430,24 @@ public <T> Maybe<MonadPlus<stream>> monadPlus() {
return Maybe.just(Instances.monadPlus());
}

@Override
public <T> MonadRec<stream> monadRec() {
return Instances.monadRec();
}

@Override
public <T> Maybe<MonadPlus<stream>> monadPlus(Monoid<Higher<stream, T>> m) {
return Maybe.just(Instances.monadPlus(m));
}

@Override
public <C2, T> Maybe<Traverse<stream>> traverse() {
return Maybe.just(Instances.traverse());
public <C2, T> Traverse<stream> traverse() {
return Instances.traverse();
}

@Override
public <T> Maybe<Foldable<stream>> foldable() {
return Maybe.just(Instances.foldable());
public <T> Foldable<stream> foldable() {
return Instances.foldable();
}

@Override
Expand Down Expand Up @@ -588,6 +646,14 @@ public static <T> MonadPlus<stream> monadPlus(Monoid<Higher<stream,T>> m){
Monoid<Higher<stream,T>> m2= (Monoid)m;
return General.monadPlus(monadZero(),m2);
}
public static <T> MonadRec<stream> monadRec(){
return new MonadRec<stream>() {
@Override
public <T, R> Higher<stream, R> tailRec(T initial, Function<? super T, ? extends Higher<stream, ? extends Xor<T, R>>> fn) {
return widen(Streams.tailRecXor(initial,fn.andThen(StreamKind::narrow)));
}
};
}

/**
* @return Type class for traversables with traverse / sequence operations
Expand Down Expand Up @@ -632,9 +698,24 @@ public static <C2,T> Traverse<stream> traverse(){
* @return Type class for folding / reduction operations
*/
public static <T> Foldable<stream> foldable(){
BiFunction<Monoid<T>,Higher<stream,T>,T> foldRightFn = (m, l)-> ReactiveSeq.fromIterable(StreamKind.narrow(l)).foldRight(m);
BiFunction<Monoid<T>,Higher<stream,T>,T> foldLeftFn = (m, l)-> ReactiveSeq.fromIterable(StreamKind.narrow(l)).reduce(m);
return General.foldable(foldRightFn, foldLeftFn);

return new Foldable<stream>() {
@Override
public <T> T foldRight(Monoid<T> monoid, Higher<stream, T> ds) {
return StreamKind.narrow(ds).foldRight1((a,b)->monoid.apply(a,b),monoid.zero());
}

@Override
public <T> T foldLeft(Monoid<T> monoid, Higher<stream, T> ds) {
return StreamKind.narrow(ds).foldLeft((a,b)->monoid.apply(a,b),monoid.zero());
}

@Override
public <T, R> R foldMap(Monoid<R> mb, Function<? super T, ? extends R> fn, Higher<stream, T> nestedA) {
return StreamKind.narrow(nestedA).foldLeft((a,b)->mb.apply(a,fn.apply(b)),mb.zero());
}
};

}

private static <T> StreamKind<T> concat(StreamKind<T> l1, StreamKind<T> l2){
Expand Down Expand Up @@ -725,10 +806,10 @@ public static <S, P> Nested<stream,Higher<xor,S>, P> xor(Stream<Xor<S, P>> neste
StreamKind<Higher<Higher<xor,S>, P>> y = (StreamKind)x;
return Nested.of(y,Instances.definitions(),Xor.Instances.definitions());
}
public static <S,T> Nested<stream,Higher<reader,S>, T> reader(Stream<Reader<S, T>> nested){
public static <S,T> Nested<stream,Higher<reader,S>, T> reader(Stream<Reader<S, T>> nested, S defaultValue){
StreamKind<Reader<S, T>> x = widen(nested);
StreamKind<Higher<Higher<reader,S>, T>> y = (StreamKind)x;
return Nested.of(y,Instances.definitions(),Reader.Instances.definitions());
return Nested.of(y,Instances.definitions(),Reader.Instances.definitions(defaultValue));
}
public static <S extends Throwable, P> Nested<stream,Higher<Witness.tryType,S>, P> cyclopsTry(Stream<cyclops.control.Try<P, S>> nested){
StreamKind<cyclops.control.Try<P, S>> x = widen(nested);
Expand Down Expand Up @@ -783,11 +864,11 @@ public static <S, P> Nested<Higher<xor,S>,stream, P> xor(Xor<S, Stream<P>> neste

return Nested.of(x,Xor.Instances.definitions(),Instances.definitions());
}
public static <S,T> Nested<Higher<reader,S>,stream, T> reader(Reader<S, Stream<T>> nested){
public static <S,T> Nested<Higher<reader,S>,stream, T> reader(Reader<S, Stream<T>> nested,S defaultValue){

Reader<S, Higher<stream, T>> x = nested.map(StreamKind::widenK);

return Nested.of(x,Reader.Instances.definitions(),Instances.definitions());
return Nested.of(x,Reader.Instances.definitions(defaultValue),Instances.definitions());
}
public static <S extends Throwable, P> Nested<Higher<Witness.tryType,S>,stream, P> cyclopsTry(cyclops.control.Try<Stream<P>, S> nested){
cyclops.control.Try<Higher<stream,P>, S> x = nested.map(StreamKind::widenK);
Expand Down

0 comments on commit 2200285

Please sign in to comment.