-
-
Save cboudereau/4e4668cb7ceac2c65ec5e9571f20e7dd to your computer and use it in GitHub Desktop.
package com.adt; | |
import static org.junit.jupiter.api.Assertions.assertEquals; | |
import static org.junit.jupiter.api.Assertions.assertTrue; | |
import org.junit.jupiter.api.Test; | |
public class AdtTest { | |
sealed interface Value<T extends Comparable<T>> extends Comparable<Value<T>> permits Value.Fixed, Value.Infinite { | |
static record Tuple<L, R>(L fst, R snd) { | |
} | |
public static final record Fixed<T extends Comparable<T>>(T value) implements Value<T> { | |
} | |
public static final record Infinite<T extends Comparable<T>>() implements Value<T> { | |
} | |
public static <T extends Comparable<T>> Fixed<T> fixed(final T value) { | |
return new Fixed<>(value); | |
} | |
public static <T extends Comparable<T>> Infinite<T> infinite() { | |
return new Infinite<>(); | |
} | |
@Override | |
default int compareTo(final Value<T> o) { | |
return switch (new Tuple<>(this, o)) { | |
case Tuple<Value<T>, Value<T>>(Value.Infinite<T> fst, Value.Infinite<T> snd) -> 0; | |
case Tuple<Value<T>, Value<T>>(Value.Infinite<T> fst, Value.Fixed<T> snd) -> 1; | |
case Tuple<Value<T>, Value<T>>(Value.Fixed<T> fst, Value.Infinite<T> snd) -> -1; | |
case Tuple<Value<T>, Value<T>>(Value.Fixed<T> fst, Value.Fixed<T> snd) -> | |
fst.value.compareTo(snd.value); | |
}; | |
} | |
default boolean isGreaterThan(final Value<T> o) { | |
return this.compareTo(o) > 0; | |
} | |
default boolean isLessThan(final Value<T> o) { | |
return this.compareTo(o) < 0; | |
} | |
} | |
@Test | |
public void compareToTest() { | |
assertEquals(0, Value.infinite().compareTo(Value.infinite())); | |
assertEquals(0, Value.fixed(1).compareTo(Value.fixed(1))); | |
assertTrue(Value.fixed(1).isLessThan(Value.infinite())); | |
assertTrue(Value.fixed(2).isGreaterThan(Value.fixed(1))); | |
assertTrue(Value.fixed(1).isLessThan(Value.fixed(2))); | |
} | |
} |
I finally got the trick to simplify the pattern matching switch expression by using a product pattern matching but still, it is required to add a default case even if it is totally covered : https://gist.github.com/cboudereau/4e4668cb7ceac2c65ec5e9571f20e7dd#file-adtordtest-java-L36
It looks like that the https://openjdk.org/jeps/441 is not solving the issue with the latest preview of java 21 and still have "A switch expression should have a default case" error when trying to remove the useless default case
Here is an interesting discussion on amber-dev : https://mail.openjdk.org/pipermail/amber-dev/2023-May/008076.html
Bug tracker : https://bugs.openjdk.org/browse/JDK-8300542
There is also jacoco exhaustiveness issue already tracked : jacoco/jacoco#1211
This version works perfectly with JDK 21 but the vscode extension "Language Support for Java(TM) by Red Hat" is complaining (it might be compatible with the JDK 20 even if it is a pre-release version v1.22.2023090904)
The rust version : https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=90bc78702650e8bd12af9efdd71d969a