Skip to content

Instantly share code, notes, and snippets.

@tomaszpolanski
Last active August 29, 2015 14:14
Show Gist options
  • Save tomaszpolanski/4861379400c19e007791 to your computer and use it in GitHub Desktop.
Save tomaszpolanski/4861379400c19e007791 to your computer and use it in GitHub Desktop.
Implementation of optionan value from functional languages
package com.tomaszpolanski.androidsandbox.utils.option;
import com.android.internal.util.Predicate;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
public final class None<A> extends Option<A> {
None() { }
@Override
public void iter(final Action1<A> action) {
// Do nothing
}
@Override
public <B> Option<B> map(final Func1<A, B> f) {
return NONE;
}
@Override
public <B> Option<B> flatMap(final Func1<A, Option<B>> f) {
return NONE;
}
@Override
public Option<A> filter(final Predicate<? super A> predicate) {
return NONE;
}
@Override
public Option<A> orOption(final Func0<Option<A>> f) {
return f.call();
}
@Override
public A orDefault(final Func0<A> def) {
return def.call();
}
@Override
public A get() {
throw new IllegalStateException();
}
@Override
public <R> Option<R> ofType(Class<R> type) {
return Option.NONE;
}
@Override
public void match(final Action1<A> fSome, final Action0 fNone) {
fNone.call();
}
@Override
public <R> R matchResult(final Func1<A, R> fSome, final Func0<R> fNone) {
return fNone.call();
}
@Override
public <B, C> Option<C> lift(final Option<B> optionB, final Func2<A, B, C> f) {
return NONE;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
package com.tomaszpolanski.androidsandbox.utils.option;
import com.android.internal.util.Predicate;
import com.tomaszpolanski.androidsandbox.utils.result.Result;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
public abstract class Option<A> {
public static final None NONE = new None();
public abstract void iter(final Action1<A> action);
public abstract <B> Option<B> map(final Func1<A, B> f);
public abstract <B> Option<B> flatMap(final Func1<A, Option<B>> f);
public abstract Option<A> filter(final Predicate<? super A> predicate);
public abstract Option<A> orOption(final Func0<Option<A>> f);
public abstract A orDefault(final Func0<A> def);
public abstract A get();
public static <A> Some<A> some(final A value) {
return new Some(value);
}
public static <A> None<A> none() {
return NONE;
}
public abstract <R> Option<R> ofType(final Class<R> type);
public static <A> Option<A> asOption(final A value) {
return value == null ? none() : some(value);
}
public static <A> Option<A> tryAsOption(final Func0<A> f) {
try {
return Option.asOption(f.call());
} catch (Exception e) {
return NONE;
}
}
public abstract void match( final Action1<A> fSome, final Action0 fNone);
public abstract <R> R matchResult( final Func1<A, R> fSome, final Func0<R> fNone);
public Option<A> id() {
return this;
}
public abstract <B,C> Option<C> lift(final Option<B> optionB, final Func2<A, B, C> f);
public Option<A> log(final String message) {
Log.e(message, this.toString());
return this;
}
}
package com.tomaszpolanski.androidsandbox.utils.option;
import com.android.internal.util.Predicate;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
public final class Some<A> extends Option<A> {
private final A mValue;
Some(A value) {
mValue = value;
}
@Override
public void iter(final Action1<A> action) {
action.call(mValue);
}
@Override
public <B> Option<B> map(final Func1<A, B> f) {
return some(f.call(mValue));
}
@Override
public <B> Option<B> flatMap(final Func1<A, Option<B>> f) {
return f.call(mValue);
}
@Override
public Option<A> filter(final Predicate<? super A> predicate) {
return predicate.apply(mValue) ? this : NONE;
}
@Override
public Option<A> orOption(final Func0<Option<A>> f) {
return this;
}
@Override
public A orDefault(final Func0<A> def) {
return mValue;
}
@Override
public A get() {
return mValue;
}
@Override
public <R> Option<R> ofType(Class<R> type) {
return type.isInstance(mValue) ? Option.asOption(type.cast(mValue)) : Option.NONE;
}
@Override
public void match(final Action1<A> fSome, final Action0 fNone) {
fSome.call(mValue);
}
@Override
public <R> R matchResult(final Func1<A, R> fSome, final Func0<R> fNone) {
return fSome.call(mValue);
}
@Override
public <B, C> Option<C> lift(final Option<B> optionB, final Func2<A, B, C> f) {
return optionB.map(b -> f.call(mValue, b));
}
@Override
public boolean equals(final Object o) {
return Option.asOption(o)
.filter(obj -> obj instanceof Some)
.map(obj -> (Some) obj)
.filter(some -> some.get().equals(mValue)) != Option.NONE;
}
@Override
public String toString() {
return mValue.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment