Skip to content

Instantly share code, notes, and snippets.

@danhyun
Last active May 27, 2024 17:38
Show Gist options
  • Save danhyun/fda27d5682b7dbed151b to your computer and use it in GitHub Desktop.
Save danhyun/fda27d5682b7dbed151b to your computer and use it in GitHub Desktop.
`Reader` and `TryReader` monads as demonstrated by Mario Fusco (@mariofusco) Devoxx 2015
public class Reader<R, A> {
private final Function<R, A> run;
public Reader(Function<R, A> run) { this.run = run; }
public <B> Reader<R, B> map(Function<A, B> f) {
return new Reader<>( r -> f.apply((apply(r))) );
}
public <B> Reader<R, B> flatMap(Function<A, Reader<R, B>> f) {
return new Reader<>( r -> f.apply(apply(r)).apply(r) );
}
public A apply(R r) {
return run.apply(r);
}
}
public class TryReader<R, A> {
private final Function<R, Try<A>> run;
public TryReader(Function<R, Try<A>> run) { this.run = run; }
public <B> TryReader<R, B> map(Function<A, B> f) {
return new TryReader<>(r -> apply(r).map(f::apply));
}
public <B> TryReader<R, B> flatMap(Function<A, TryReader<R, B>> f) {
return new TryReader<>(r -> apply(r).flatMap(a -> f.apply(a).apply(r)));
}
public <B> TryReader<R, B> mapReader(Function<A, Reader<R, B>> f) {
return new TryReader<>(r -> apply(r).map( a -> f.apply(a).apply(r) ) );
}
public Try<A> apply(R r) { return run.apply(r); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment