Skip to content

Instantly share code, notes, and snippets.

@jhusain
Created January 17, 2018 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhusain/ae2d9ccd39108042ee444ab531c4c6af to your computer and use it in GitHub Desktop.
Save jhusain/ae2d9ccd39108042ee444ab531c4c6af to your computer and use it in GitHub Desktop.
import cyclops.control.Unrestricted;
import io.reactivex.Observable;
public class ObservableInterpreter {
public static <R> Observable<R> interpret(Unrestricted<R> program){
//walk the Free data structure and handle each command,
//by delegating to the appropriate method
return program.resume(Command.decoder())
.visit(r -> matchCommand(r), r -> Observable.just(r));
}
private static <R> Observable<R> matchCommand(Command<R> command){
if(command instanceof Command.Done)
return handleDone((Command.Done<R>)command);
else if (command instanceof Command.GetVideosCommand)
return handleGetVideos((Command.GetVideosCommand<Unrestricted<R>>)command);
throw new IllegalArgumentException("Unknown command " + command);
}
static <R> Observable<R> handleGetVideos(Command.GetVideosCommand<Unrestricted<R>> output){
VideoService videoService = new VideoService();
// currently mocked
return output.visit((a, next) -> interpret(next.apply(new Video(23))));
}
static <T> Observable<T> handleDone(Command.Done<T> done){
return Observable.empty();
}
}
import com.aol.cyclops2.types.functor.Transformable;
import cyclops.control.Unrestricted;
import io.reactivex.Observable;
import org.jooq.lambda.tuple.Tuple2;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
//Command from https://github.com/xuwei-k/free-monad-java
abstract class Command<T> implements Transformable<T> {
public final static <T> Function<Transformable<Unrestricted<T>>,Command<Unrestricted<T>>> decoder() {
return c->(Command<Unrestricted<T>>)c;
}
public static Unrestricted<Video> getVideos(List<Integer> videoIds){
return Unrestricted.liftF(new GetVideosCommand<>(videoIds, (v) -> null));
}
public static Unrestricted<Void> done(){
return Unrestricted.liftF(new Done<Void>());
}
public static <A> Unrestricted<A> just(final A a){
return Unrestricted.done(a);
}
public Command(){}
static class GetVideosCommand<T> extends Command<T> {
private final List<Integer> videoIds;
private final Function<Video, T> next;
private GetVideosCommand(final List<Integer> videoIds, final Function<Video,T> next) {
super();
this.videoIds = videoIds;
this.next = next;
}
public <R> R visit(final BiFunction<List<Integer>, Function<Video, T>, ? extends R> output) {
return output.apply(videoIds, next);
}
@Override
public <R> Command<R> map(final Function<? super T,? extends R> f) {
return new GetVideosCommand<>(videoIds, (video) -> f.apply(this.next.apply(video)));
}
}
static class GetRatingsCommand<T> extends Command<T> {
private final List<Integer> videoIds;
private final Function<Tuple2<Integer, Double>, T> next;
private GetRatingsCommand(final List<Integer> videoIds, final Function<Tuple2<Integer, Double>,T> next) {
super();
this.videoIds = videoIds;
this.next = next;
}
public <R> R visit(final BiFunction<List<Integer>, Function<Tuple2<Integer, Double>, T>, ? extends R> output) {
return output.apply(videoIds, next);
}
@Override
public <R> Command<R> map(final Function<? super T,? extends R> f) {
return new GetRatingsCommand<>(videoIds, (tuple) -> f.apply(this.next.apply(tuple)));
}
}
static final class Done<T> extends Command<T> {
public <T> T visit(final T done) {
return done;
}
@Override
public <R> Command<R> map(final Function<? super T,? extends R> f) {
return new Done<>();
}
}
}
@jhusain
Copy link
Author

jhusain commented Jan 17, 2018

Error:(13, 23) java: incompatible types: inferred type does not conform to equality constraint(s)
inferred: R
equality constraints(s): R,cyclops.control.Unrestricted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment