Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Java code repetition requiring refactoring.
package RefactoringPuzzle;
abstract class Func<T, U> {
abstract U apply(T t);
}
abstract class IntRdr<A> {
abstract A read(int i);
<B> IntRdr<B> map(final Func<A, B> f) {
return new IntRdr<B>() {
B read(int i) {
return f.apply(IntRdr.this.read(i));
}
};
}
<B> IntRdr<B> bind(final Func<A, IntRdr<B>> f) {
return new IntRdr<B>() {
B read(int i) {
return f.apply(IntRdr.this.read(i)).read(i);
}
};
}
static <A> IntRdr<A> apply(final A a) {
return new IntRdr<A>() {
A read(int _) {
return a;
}
};
}
}
abstract class Option<A> {
abstract <X> X fold(Func<A, X> some, X none);
<B> Option<B> map(final Func<A, B> f) {
return new Option<B>() {
<X> X fold(final Func<B, X> some, X none) {
return Option.this.fold(new Func<A, X>(){
X apply(A a) {
return some.apply(f.apply(a));
}
}, none);
}
};
}
<B> Option<B> bind(final Func<A, Option<B>> f) {
return new Option<B>() {
<X> X fold(final Func<B, X> some, final X none) {
return Option.this.fold(new Func<A, X>(){
X apply(A a) {
return f.apply(a).fold(some, none);
}
}, none);
}
};
}
static <A> Option<A> apply(final A a) {
return new Option<A>() {
<X> X fold(Func<A, X> some, X none) {
return some.apply(a);
}
};
}
}
abstract class List<A> {
abstract <X> X foldRight(Func<A, Func<X, X>> f, X x);
// Return all the Some values, or None if not all are Some.
static <A> Option<List<A>> runOptions(List<Option<A>> x) {
return x.foldRight(new Func<Option<A>, Func<Option<List<A>>, Option<List<A>>>>(){
Func<Option<List<A>>, Option<List<A>>> apply(final Option<A> a) {
return new Func<Option<List<A>>, Option<List<A>>>() {
Option<List<A>> apply(final Option<List<A>> b) {
return a.bind(new Func<A, Option<List<A>>>(){
Option<List<A>> apply(final A aa) {
return b.map(new Func<List<A>, List<A>>(){
List<A> apply(List<A> bb) {
return bb.prepend(aa);
}
});
}
});
}
};
}
}, Option.apply(List.<A>nil()));
}
// Apply an Int to a list of int readers and return the list of return values.
static <A> IntRdr<List<A>> runIntRdrs(List<IntRdr<A>> x) {
return x.foldRight(new Func<IntRdr<A>, Func<IntRdr<List<A>>, IntRdr<List<A>>>>(){
Func<IntRdr<List<A>>, IntRdr<List<A>>> apply(final IntRdr<A> a) {
return new Func<IntRdr<List<A>>, IntRdr<List<A>>>() {
IntRdr<List<A>> apply(final IntRdr<List<A>> b) {
return a.bind(new Func<A, IntRdr<List<A>>>(){
IntRdr<List<A>> apply(final A aa) {
return b.map(new Func<List<A>, List<A>>(){
List<A> apply(List<A> bb) {
return bb.prepend(aa);
}
});
}
});
}
};
}
}, IntRdr.apply(List.<A>nil()));
}
List<A> prepend(final A a) {
return new List<A>() {
<X> X foldRight(Func<A, Func<X, X>> f, X x) {
return f.apply(a).apply(this.foldRight(f, x));
}
};
}
static <A> List<A> nil() {
return new List<A>() {
<X> X foldRight(Func<A, Func<X, X>> f, X x) {
return x;
}
};
}
}
// Code Duplication
// *********** ************* ******* *********
// static <A> Option<List<A>> runOptions(List<Option<A>> x) {
// static <A> IntRdr<List<A>> runIntRdrs(List<IntRdr<A>> x) {
// **************************** ********** *********** **************
// return x.foldRight(new Func<Option<A>, Func<Option<List<A>>, Option<List<A>>>>(){
// return x.foldRight(new Func<IntRdr<A>, Func<IntRdr<List<A>>, IntRdr<List<A>>>>(){
// ***** *********** *********************** ********
// Func<Option<List<A>>, Option<List<A>>> apply(final Option<A> a) {
// Func<IntRdr<List<A>>, IntRdr<List<A>>> apply(final IntRdr<A> a) {
// **************** *********** **************
// return new Func<Option<List<A>>, Option<List<A>>>() {
// return new Func<IntRdr<List<A>>, IntRdr<List<A>>>() {
// ********************** **************
// Option<List<A>> apply(final Option<List<A>> b) {
// IntRdr<List<A>> apply(final IntRdr<List<A>> b) {
// ************************** *************
// return a.bind(new Func<A, Option<List<A>>>(){
// return a.bind(new Func<A, IntRdr<List<A>>>(){
// *****************************
// Option<List<A>> apply(final A aa) {
// IntRdr<List<A>> apply(final A aa) {
// ******************************************
// return b.map(new Func<List<A>, List<A>>(){
// return b.map(new Func<List<A>, List<A>>(){
// ***************************
// List<A> apply(List<A> bb) {
// List<A> apply(List<A> bb) {
// **********************
// return bb.prepend(aa);
// return bb.prepend(aa);
//
// *** ***********************
// }, Option.apply(List.<A>nil()));
// }, IntRdr.apply(List.<A>nil()));
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment