Skip to content

Instantly share code, notes, and snippets.

@forax
Created April 1, 2024 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forax/5b3ebb724260ae564fa298c3ca4e9062 to your computer and use it in GitHub Desktop.
Save forax/5b3ebb724260ae564fa298c3ca4e9062 to your computer and use it in GitHub Desktop.
import java.util.Objects;
public interface FunctionalDeconstructionDemo {
// Example 1: Optional
public final class Optional<T> {
private T value;
private Optional(T value) {
this.value = value;
}
public static <T> Optional<T> empty() {
return new Optional<>(null);
}
public static <T> Optional<T> of(T value) {
Objects.requireNonNull(value);
return new Optional<>(value);
}
public /*value*/ record $CarrierPresent<T>(T value) {}
public /*pattern*/ $CarrierPresent<T> asPresent() {
if (value == null) {
return null;
}
return new $CarrierPresent<>(value);
}
public /*value*/ record $CarrierEmpty() {}
public /*pattern*/ $CarrierEmpty asEmpty() {
if (value != null) {
return null;
}
return new $CarrierEmpty();
}
}
static void optionalTest() {
var point = Optional.of("foo");
var result = switch (point) {
case Optional<String> opt when opt.asEmpty() instanceof Optional.$CarrierEmpty() -> "";
case Optional<String> opt when opt.asPresent() instanceof Optional.$CarrierPresent<String>(String s) -> s;
default -> throw new MatchException("boom !", null);
};
System.out.println(result);
}
// Example 2: Map.Entry
public interface Map<K,V> {
public interface Entry<K,V> {
public /*value*/ record $Carrier<K, V>(K key, V value) {}
public /*pattern*/ $Carrier/*!*/<K, V> asEntry();
}
public static <K,V> Map.Entry<K,V> entry(K key, V value) {
return () -> new Entry.$Carrier<>(key, value);
}
}
static void mapEntryTest() {
var entry = Map.entry("ben", 10);
var result = switch (entry) {
case Map.Entry<String,Integer> e when e.asEntry() instanceof Map.Entry.$Carrier<String, Integer>(String key, Integer value) -> key + "=" + value;
default -> throw new MatchException("boom !", null);
};
System.out.println(result);
}
// Example 3: Point
public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public /*value*/ record $Carrier(int x, int y) {}
public static /*pattern*/ $Carrier/*!*/ deconstructor(Point that) {
Objects.requireNonNull(that);
return new $Carrier(that.x, that.y);
}
}
static void pointTest() {
var point = new Point(1, 2);
var result = switch (point) {
case Point p when Point.deconstructor(p) instanceof Point.$Carrier/*!*/(int x, int y) -> x + y;
default -> throw new MatchException("boom !", null);
};
System.out.println(result);
}
public static void main(String[] args) {
optionalTest();
mapEntryTest();
pointTest();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment