Skip to content

Instantly share code, notes, and snippets.

@ankurpshah
Created July 27, 2013 09:19
Show Gist options
  • Save ankurpshah/6094357 to your computer and use it in GitHub Desktop.
Save ankurpshah/6094357 to your computer and use it in GitHub Desktop.
Functional Null
package option;
public final class None<T> extends Option<T> {
public static class NoneHasNoValue extends RuntimeException {}
public None() {}
public boolean hasValue() { return false; }
public T get() { throw new NoneHasNoValue(); }
@Override
public String toString() { return "None"; }
@Override
public boolean equals(Object other) {
return (other == null || other.getClass() != None.class) ? false : true;
}
}
@Override
public int hashCode() { return -1; }
ackage option;
public abstract class Option<T> {
public abstract boolean hasValue();
public abstract T get();
}
public T getOrElse(T alternative) {
return hasValue() == true ? get() : alternative;
package option;
public final class Some<T> extends Option<T> {
private final T value;
public Some(T value) { this.value = value; }
public boolean hasValue() { return true; }
public T get() { return value; }
@Override
public String toString() { return "Some("+value+")"; }
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != Some.class)
return false;
Some<?> that = (Some<?>) other;
Object thatValue = that.get();
return value.equals(thatValue);
}
}
@Override
public int hashCode() { return 37 * value.hashCode(); }
package
option;
import java.util.*;
import org.junit.*;
import static org.junit.Assert.*;
public class OptionTest {
private List<Option<String>> names = null;
@Before
public void setup() {
names = new ArrayList<Option<String>>();
names.add(new Some<String>("Dean"));
names.add(new None<String>());
names.add(new Some<String>("Wampler"));
}
@Test
public void getOrElseUsesValueForSomeAndAlternativeForNone() {
String[] expected = { "Dean", "Unknown!", "Wampler"};;
System.out.println("*** Using getOrElse:");
for (int i = 0; i < names.size(); i++) {
Option<String> name = names.get(i);
String value = name.getOrElse("Unknown!");
System.out.println(name + ": " + value);
assertEquals(expected[i], value);
}
}
Designing Types | 19
@Test
public void hasNextWithGetUsesOnlyValuesForSomes() {
String[] expected = { "Dean", null, "Wampler"};;
System.out.println("*** Using hasValue:");
for (int i = 0; i < names.size(); i++) {
Option<String> name = names.get(i);
if (name.hasValue()) {
String value = name.get();
System.out.println(name + ": " + value);
assertEquals(expected[i], value);
}
}
}
static Option<String> wrap(String s) {
if (s == null)
return new None<String>();
else
return new Some<String>(s);
}
@Test
public void exampleMethodReturningOption() {
System.out.println("*** Method that Returns an Option:");
Option<String> opt1 = wrap("hello!");
System.out.println("hello! -> "+opt1);
assertEquals(Some.class, opt1.getClass());
assertEquals("hello!", opt1.get());
}
}
Option<String> opt2 = wrap(null);
System.out.println("null -> "+opt2);
assertEquals(None.class, opt2.getClass());
assertEquals("str", opt2.getOrElse("str"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment