Skip to content

Instantly share code, notes, and snippets.

Created June 19, 2016 03:16
Show Gist options
  • Save anonymous/c3094b25153e4a203705cf14623f71aa to your computer and use it in GitHub Desktop.
Save anonymous/c3094b25153e4a203705cf14623f71aa to your computer and use it in GitHub Desktop.
package org.gtri.arfam.acs.interpreter;
import fj.F;
import fj.F2;
import fj.data.List;
public interface Operation<A> {
interface Free<A> {
class Return<B> implements Free<B> {
private final B b;
public 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;
}
}
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);
}
}
<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 FreeOperation {
public static <B> Free<List<B>> sequence(List<Free<B>> listFreeB) {
F2<Free<B>, Free<List<B>>, Free<List<B>>> folder =
(freeB, freeListB) ->
freeB.flatMap(b ->
freeListB.map(listB ->
List.cons(b, listB)));
return listFreeB.foldRight(folder, new Free.Return<List<B>>(List.nil()));
}
}
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