Created
April 1, 2024 10:41
-
-
Save forax/5b3ebb724260ae564fa298c3ca4e9062 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 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