Skip to content

Instantly share code, notes, and snippets.

@danidiaz
Last active April 3, 2018 05:55
Show Gist options
  • Select an option

  • Save danidiaz/9cc451c841bbd7ad9330f7b2276411c5 to your computer and use it in GitHub Desktop.

Select an option

Save danidiaz/9cc451c841bbd7ad9330f7b2276411c5 to your computer and use it in GitHub Desktop.
Java's try-with-resources as a Monad, just for the kicks. Very crude: verbose, nests exceptions with each bind, can't return values.
package danisoft.posts;
import java.io.File;
import java.io.FileReader;
public class Main {
public static void main(String[] args) {
Managed.manage(() -> fileReader(new File("/tmp/dummyFileA")))
.flatMap(r1 -> Managed.manage(() -> fileReader(new File("/tmp/dummyFileB")))
.flatMap(r2 -> Managed.of(new Pair<FileReader,FileReader>(r1,r2))))
.use(readerpair -> {
// do file reading stuff here
return;
});
}
private static FileReader fileReader(File path) {
try {
return new FileReader(path);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static class Pair<A,B> {
final A first;
final B second;
public Pair(A first, B second) {
super();
this.first = first;
this.second = second;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
}
}
package danisoft.posts;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class Managed<T> {
private final Consumer<Consumer<T>> cont;
private Managed(Consumer<Consumer<T>> cont) {
super();
this.cont = cont;
}
public static final <T extends AutoCloseable> Managed<T> manage(Supplier<T> supplier) {
return new Managed<>(consumer -> {
try {
try (T resource = supplier.get()) {
consumer.accept(resource);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
public void use(Consumer<T> consumer) {
this.cont.accept(consumer);
}
/**
* Monadic constructor.
* @param t
* @return
*/
public static final <T> Managed<T> of(T t) {
return new Managed<>(consumer -> consumer.accept(t));
}
/**
* Monadic bind.
* @param func
* @return
*/
public <R> Managed<R> flatMap(Function<T,Managed<R>> func) {
return new Managed<R>(innercont -> {
this.cont.accept(resource -> func.apply(resource).use(innercont));
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment