Skip to content

Instantly share code, notes, and snippets.

@aryairani
Last active March 25, 2016 01:56
Show Gist options
  • Save aryairani/94a2cd540cbfc5a3847c to your computer and use it in GitHub Desktop.
Save aryairani/94a2cd540cbfc5a3847c to your computer and use it in GitHub Desktop.
class Bind<A, B> implements Free<B> {
private final Operation<A> operation;
private final F<A, Free<B>> fInner;
private Bind(Operation<A> operation, F<A, Free<B>> fInner) {
this.operation = operation;
this.fInner = fInner;
}
public <C> Free<C> flatMap(F<B, Free<C>> f) {
return new Bind<>(operation, a -> fInner.f(a).flatMap(f));
}
public B run(Interpreter interpreter) {
return fInner.f(interpreter.f(operation)).run(interpreter);
}
}
interface Free<A> {
<B> Free<B> flatMap(F<A, Free<B>> f);
default <B> Free<B> map(F<A, B> f) {
return flatMap(a -> new Return<>(f.f(a)));
}
A run(Interpreter interpreter);
}
class Return<B> implements Free<B> {
private final B b;
private Return(B b) {
this.b = b;
}
public <C> Free<C> flatMap(F<B, Free<C>> f) {
return f.f(b);
}
public B run(Interpreter interpreter) {
return b;
}
}
package org.gtri.framework;
public interface Interpreter {
<A> A f(Operation<A> operation);
}
package org.gtri.framework;
import fj.F;
public interface Operation<A> {
default Free<A> free() {
return new Free.Bind<>(this, Free.Return::new);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment