Created
March 6, 2012 10:16
-
-
Save jonseymour/1985544 to your computer and use it in GitHub Desktop.
Option v2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
With getters exposed as meta data, one can write an expression like this. | |
final Option<String> opt = OptionFactory.option(foo).with(FooMeta.getBar.deref(BarMeta.getName)); | |
final String name = opt.isSome() ? opt.some() : ""; | |
useName(name); | |
or: | |
final String name = OptionFactory.option(foo).with(FooMeta.getBar.deref(BarMeta.getName)).orAlternate(""); | |
useName(name); | |
or: | |
for (String name : OptionFactory.option(foo).with(FooMeta.getBar.deref(BarMeta.getName))) { | |
useName(name); | |
return; | |
} | |
useName(""); | |
or (less likely): | |
OptionFactory.option(foo).with(FooMeta.getBar.deref(BarMeta.getName)).with(new UnaryOp<String.Void>() { | |
public Void apply(String name) { | |
useName(name); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.jonseymour.v1.option; | |
import java.util.NoSuchElementException; | |
import org.jonseymour.v1.functional.Unary; | |
import org.junit.Test.None; | |
/** | |
* Defines an {@link Option} type. | |
* <p> | |
* Several access patterns are supported. | |
* <p> | |
* The Iterable pattern: | |
* <pre> | |
* // assuming Option<T> foo() | |
* | |
* for (T t : foo()) { | |
* doSomething(t); | |
* return; | |
* } | |
* doDefaultThing(); | |
* </pre> | |
* <p> | |
* The 'with Unary' pattern: | |
* </p> | |
* <pre> | |
* Option<String> opt = foo() | |
* .with(FooMeta.getBar) | |
* .with(BarMeta.getName); | |
* </pre> | |
* The 'checked access' pattern: | |
* <pre> | |
* final Option<Tgt; opt = foo(); | |
* opt.some(); // illegal: access to some() not guarded by call to isSome(), isNone(). | |
* if (opt.isSome()) { | |
* final T t = opt.some(); | |
* doSomething(t); | |
* } else { | |
* doDefaultThing(); | |
* } | |
* </pre> | |
* The 'orAlternate' pattern: | |
* <pre> | |
* final Option<String> opt = foo(); | |
* final String someString = opt.orAlternate(""); | |
* </pre> | |
* | |
* | |
* </pre> | |
* @author jseymour | |
* @inspiredBy http://eng.wealthfront.com/2010/05/better-option-for-java.html | |
* @param <T> | |
*/ | |
public interface Option<T> | |
extends Iterable<T>, Cloneable | |
{ | |
public abstract Option<T> clone(); | |
/** | |
* Execute the specified {@link Unary} with the {@link Impl}'s value, if | |
* there is one. Return an Option with an instance of the {@link Unary}'s | |
* output type. | |
* <p> | |
* If the {@link Impl} does not have a value, return {@link None} without | |
* running the {@link Unary}. | |
* | |
* @param unary | |
* The unary operation to be called, if Option has a value. | |
* @return An instance of Option<O>. | |
*/ | |
public abstract <O> Option<O> with(Unary<T, O> unary); | |
/** | |
* @return Answers true if there is a non-null value associated with the {@link Impl}. | |
*/ | |
public abstract boolean isSome(); | |
/** | |
* @return Answers true if there is no non-null value associated with the {@link Impl}. | |
*/ | |
public abstract boolean isNone(); | |
/** | |
* Answers the {@link Impl}'s value. | |
* | |
* @return Answers a reference to the value, but only if isNone() and isSome() has been called first. | |
* @throws NoSuchElementException If isNone() is false or if isSome() or isNone() has not been called immediately before a call to this method. | |
*/ | |
public abstract T some(); | |
/** | |
* Answers either the receiver's value (if not null) or <code>alternate</code> otherwise. | |
* | |
* @param alternate An alternate value which must not be null. | |
* @return The {@link Impl}'s value or <code>alternate</code>, if the receiving {@link Impl} {@link #isNone()}. | |
* @throws IllegalArgumentException if <code>alternate</code> is null. | |
*/ | |
public abstract T orAlternate(T alternate); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment