Skip to content

Instantly share code, notes, and snippets.

@Garciat
Created October 8, 2025 12:08
Show Gist options
  • Select an option

  • Save Garciat/0db4b5abd9981c132e8ef650ffa707bb to your computer and use it in GitHub Desktop.

Select an option

Save Garciat/0db4b5abd9981c132e8ef650ffa707bb to your computer and use it in GitHub Desktop.
interface Refinement<T> {
boolean isValid(T value);
static <T, R1 extends Refinement<T>, R2 extends Refinement<T>> And<T, R1, R2> and(R1 r1, R2 r2) {
return new And<>(r1, r2);
}
record And<T, R1 extends Refinement<T>, R2 extends Refinement<T>>(R1 r1, R2 r2)
implements Refinement<T> {
@Override
public boolean isValid(T value) {
return r1.isValid(value) && r2.isValid(value);
}
}
}
interface PositiveI extends Refinement<Integer> {
PositiveI IT = new PositiveI() {};
@Override
default boolean isValid(Integer value) {
return value > 0;
}
static PositiveI positiveI() {
return IT;
}
}
interface EvenI extends Refinement<Integer> {
EvenI IT = new EvenI() {};
@Override
default boolean isValid(Integer value) {
return value % 2 == 0;
}
static EvenI evenI() {
return IT;
}
}
interface NonEmpty<C extends Collection<?>> extends Refinement<C> {
@Override
boolean isValid(C value);
static <C extends Collection<?>> NonEmpty<C> nonEmpty() {
return value -> !value.isEmpty();
}
}
sealed interface TyEq<A, B> {
B cast(A a);
static <T> TyEq<T, T> refl() {
return new Refl<>();
}
record Refl<T>() implements TyEq<T, T> {
@Override
public T cast(T t) {
return t;
}
}
}
final class Refined<T, R extends Refinement<T>> {
private final T value;
private final R refinement;
private Refined(T value, R refinement) {
this.value = value;
this.refinement = refinement;
}
public <A extends Refinement<T>, B extends Refinement<T>> Refined<T, A> fst(
TyEq<R, Refinement.And<T, A, B>> ty) {
return new Refined<>(value, ty.cast(refinement).r1());
}
public <A extends Refinement<T>, B extends Refinement<T>> Refined<T, B> snd(
TyEq<R, Refinement.And<T, A, B>> ty) {
return new Refined<>(value, ty.cast(refinement).r2());
}
public static <T, R extends Refinement<T>> Optional<Refined<T, R>> of(T value, R refinement) {
return refinement.isValid(value)
? Optional.of(new Refined<>(value, refinement))
: Optional.empty();
}
public T value() {
return value;
}
}
class Example {
void f() {
Refined<Integer, Refinement.And<Integer, PositiveI, EvenI>> refined =
Refined.of(2, Refinement.and(PositiveI.IT, EvenI.IT)).orElseThrow();
wantPositive(refined.fst(TyEq.refl()));
wantEven(refined.snd(TyEq.refl()));
Refined<ImmutableList<Integer>, NonEmpty<ImmutableList<Integer>>> immutableListNonEmptyRefined =
Refined.of(ImmutableList.of(1, 2, 3), NonEmpty.nonEmpty()).orElseThrow();
}
void wantPositive(Refined<Integer, PositiveI> r) {
System.out.println(r.value());
}
void wantEven(Refined<Integer, EvenI> r) {
System.out.println(r.value());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment