Last active
August 14, 2018 22:03
-
-
Save chronodm/00ed54b6693dd34291de70c2ea11df67 to your computer and use it in GitHub Desktop.
Discriminated union sort of thing in Java
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
import static java.lang.System.out; | |
import java.util.function.IntUnaryOperator; | |
/** | |
* See https://softwareengineering.stackexchange.com/questions/376845/how-should-i-store-unknown-and-missing-values-in-a-variable-while-still-ret | |
*/ | |
public abstract class Measurement { | |
/** | |
* Prints: | |
* | |
* <pre> | |
* Value(4) | |
* Empty() | |
* Unknown() | |
* </pre> | |
*/ | |
public static void main(String[] args) { | |
var value = Measurement.of(2); | |
out.println(value.map(x -> x * 2)); | |
var empty = Measurement.empty(); | |
out.println(empty.map(x -> x * 2)); | |
var unknown = Measurement.unknown(); | |
out.println(unknown.map(x -> x * 2)); | |
} | |
public abstract Measurement map(IntUnaryOperator f); | |
public boolean hasValue() { | |
return false; | |
} | |
public boolean isEmpty() { | |
return false; | |
} | |
public boolean isUnknown() { | |
return false; | |
} | |
/** | |
* A measured non-empty value. | |
*/ | |
public static Value of(int value) { | |
return new Value(value); | |
} | |
/** | |
* A measured empty value. | |
*/ | |
public static Empty empty() { | |
return Empty.INSTANCE; | |
} | |
/** | |
* A measurement that has not been taken. | |
*/ | |
public static Unknown unknown() { | |
return Unknown.INSTANCE; | |
} | |
/** | |
* A measured non-empty value. | |
*/ | |
public static class Value extends Measurement { | |
private final int value; | |
private Value(int value) { | |
this.value = value; | |
} | |
@Override | |
public Measurement map(IntUnaryOperator f) { | |
return new Value(f.applyAsInt(value)); | |
} | |
@Override | |
public boolean hasValue() { | |
return true; | |
} | |
@Override | |
public String toString() { | |
return "Value(" + value + ")"; | |
} | |
} | |
/** | |
* A measured empty value. | |
*/ | |
public static class Empty extends Measurement { | |
private static final Empty INSTANCE = new Empty(); | |
private Empty() { | |
// not to be instantiated directly | |
} | |
@Override | |
public Empty map(IntUnaryOperator f) { | |
return this; | |
} | |
@Override | |
public boolean isEmpty() { | |
return true; | |
} | |
@Override | |
public String toString() { | |
return "Empty()"; | |
} | |
} | |
/** | |
* A measurement that has not been taken. | |
*/ | |
public static class Unknown extends Measurement { | |
private static final Unknown INSTANCE = new Unknown(); | |
private Unknown() { | |
// not to be instantiated directly | |
} | |
@Override | |
public Unknown map(IntUnaryOperator f) { | |
return this; | |
} | |
@Override | |
public boolean isUnknown() { | |
return true; | |
} | |
@Override | |
public String toString() { | |
return "Unknown()"; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment