Add annotations

This commit is contained in:
dfsek committed 2026-01-02 17:12:20 -07:00
1 parent 966bcab370
commit a5fe4d7928
10 files changed
+142 -66

No files matched your search

@@ -27,7 +27,7 @@ import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import static com.dfsek.terra.api.util.function.FunctionUtils.collapse; import static com.dfsek.terra.api.util.generic.data.types.Either.collapse;
public class LocateCommandAddon implements AddonInitializer { public class LocateCommandAddon implements AddonInitializer {
@@ -2,40 +2,39 @@ package com.dfsek.terra.api.util.function;
import com.dfsek.terra.api.util.generic.data.types.Either; import com.dfsek.terra.api.util.generic.data.types.Either;
import java.util.Optional; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
public final class FunctionUtils { public final class FunctionUtils {
private FunctionUtils() {} private FunctionUtils() { }
public static <T> Function<T, T> lift(Consumer<T> c) { @Contract("_ -> new")
public static <T> @NotNull Function<T, T> lift(@NotNull Consumer<T> c) {
Objects.requireNonNull(c);
return co -> { return co -> {
c.accept(co); c.accept(co);
return co; return co;
}; };
} }
@SuppressWarnings("unchecked") @Contract("_ -> fail")
public static <T, L> Either<L, T> toEither(Optional<T> o, L de) { public static <T extends Throwable, U> @NotNull U throw_(@NotNull T e) throws T {
return (Either<L, T>) o.map(Either::right).orElseGet(() -> Either.left(de));
}
public static <T> T collapse(Either<T, T> either) {
return either.collect(Function.identity(), Function.identity());
}
public static <T extends Throwable, U> U throw_(T e) throws T {
throw e; throw e;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <E extends Throwable, U> U sneakyThrow(Throwable e) throws E { @Contract("_ -> fail")
public static <E extends Throwable, U> @NotNull U sneakyThrow(@NotNull Throwable e) throws E {
throw (E) e; throw (E) e;
} }
public static <T, U> Function<T, Either<Exception, U>> liftTry(Function<T, U> f) { @Contract(pure = true, value = "_ -> new")
public static <T, U> @NotNull Function<T, Either<Exception, U>> liftTry(@NotNull Function<T, U> f) {
return s -> { return s -> {
try { try {
return Either.right(f.apply(s)); return Either.right(f.apply(s));
@@ -45,4 +44,14 @@ public final class FunctionUtils {
}; };
} }
@Contract(pure = true, value = "_ -> new")
public static <T, U> @NotNull Function<T, Either<Throwable, U>> liftTryUnsafe(@NotNull Function<T, U> f) {
return s -> {
try {
return Either.right(f.apply(s));
} catch(Throwable e) {
return Either.left(e);
}
};
}
} }
@@ -3,6 +3,10 @@ package com.dfsek.terra.api.util.generic.control;
import com.dfsek.terra.api.util.generic.data.Functor; import com.dfsek.terra.api.util.generic.data.Functor;
import com.dfsek.terra.api.util.generic.kinds.K; import com.dfsek.terra.api.util.generic.kinds.K;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
@@ -10,17 +14,21 @@ import java.util.function.Function;
* A monad is a monoid in the category of endofunctors. * A monad is a monoid in the category of endofunctors.
*/ */
public interface Monad<T, M extends Monad<?, M>> extends Functor<T, M>, K<M, T> { public interface Monad<T, M extends Monad<?, M>> extends Functor<T, M>, K<M, T> {
<T2> Monad<T2, M> bind(Function<T, Monad<T2, M>> map); @Contract(pure = true, value = "_ -> new")
<T2> @NotNull Monad<T2, M> bind(@NotNull Function<T, Monad<T2, M>> map);
<T1> Monad<T1, M> pure(T1 t); @Contract(pure = true, value = "_ -> new")
<T1> @NotNull Monad<T1, M> pure(@NotNull T1 t);
@Override @Override
default <U> Monad<U, M> map(Function<T, U> map) { @Contract(pure = true, value = "_ -> new")
return bind(map.andThen(this::pure)); default <U> @NotNull Monad<U, M> map(@NotNull Function<T, U> map) {
return bind(Objects.requireNonNull(map).andThen(this::pure));
} }
// almost all well-known applicative functors are also monads, so we can just put that here. // almost all well-known applicative functors are also monads, so we can just put that here.
default <U> Monad<U, M> apply(Monad<Function<T, U>, M> amap) { @Contract(pure = true, value = "_ -> new")
return amap.bind(this::map); default <U> @NotNull Monad<U, M> apply(@NotNull Monad<Function<T, U>, M> amap) {
return Objects.requireNonNull(amap).bind(this::map);
} }
} }
@@ -2,29 +2,41 @@ package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.data.types.Pair; import com.dfsek.terra.api.util.generic.data.types.Pair;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
public interface BiFunctor<T, U, B extends BiFunctor<?, ?, B>> { public interface BiFunctor<T, U, B extends BiFunctor<?, ?, B>> {
static <L, R, B extends BiFunctor<?, ?, B>> Consumer<BiFunctor<L, R, B>> consumeLeft(Consumer<L> consumer) { @Contract("_ -> new")
static <L, R, B extends BiFunctor<?, ?, B>> @NotNull Consumer<BiFunctor<L, R, B>> consumeLeft(@NotNull Consumer<L> consumer) {
Objects.requireNonNull(consumer);
return pair -> pair.mapLeft(p -> { return pair -> pair.mapLeft(p -> {
consumer.accept(p); consumer.accept(p);
return p; return p;
}); });
} }
static <L, R> Consumer<Pair<L, R>> consumeRight(Consumer<R> consumer) { @Contract("_ -> new")
static <L, R, B extends BiFunctor<?, ?, B>> @NotNull Consumer<BiFunctor<L, R, B>> consumeRight(@NotNull Consumer<R> consumer) {
Objects.requireNonNull(consumer);
return pair -> pair.mapRight(p -> { return pair -> pair.mapRight(p -> {
consumer.accept(p); consumer.accept(p);
return p; return p;
}); });
} }
<V> BiFunctor<V, U, B> mapLeft(Function<T, V> map); @Contract(pure = true, value = "_ -> new")
<V> BiFunctor<T, V, B> mapRight(Function<U, V> map); <V> @NotNull BiFunctor<V, U, B> mapLeft(@NotNull Function<T, V> map);
default <V, W> BiFunctor<V, W, B> bimap(Function<T, V> left, Function<U, W> right) { @Contract(pure = true, value = "_ -> new")
<V> @NotNull BiFunctor<T, V, B> mapRight(@NotNull Function<U, V> map);
@Contract(pure = true, value = "_, _-> new")
default <V, W> @NotNull BiFunctor<V, W, B> bimap(@NotNull Function<T, V> left, @NotNull Function<U, W> right) {
return mapLeft(left).mapRight(right); return mapLeft(left).mapRight(right);
} }
} }
@@ -2,9 +2,13 @@ package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.kinds.K; import com.dfsek.terra.api.util.generic.kinds.K;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function; import java.util.function.Function;
public interface Functor<T, F extends Functor<?, F>> extends K<F, T> { public interface Functor<T, F extends Functor<?, F>> extends K<F, T> {
<U> Functor<U, F> map(Function<T, U> map); @Contract(pure = true, value = "_ -> new")
<U> @NotNull Functor<U, F> map(@NotNull Function<T, U> map);
} }
@@ -3,59 +3,81 @@ package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.control.Monad; import com.dfsek.terra.api.util.generic.control.Monad;
import com.dfsek.terra.api.util.generic.data.types.Maybe; import com.dfsek.terra.api.util.generic.data.types.Maybe;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.dataflow.qual.Pure;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T, LinkedList<?>> { public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T, LinkedList<?>> {
@Override @Override
<T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map); @Contract(pure = true, value = "_ -> new")
<T2> @NotNull LinkedList<T2> bind(@NotNull Function<T, Monad<T2, LinkedList<?>>> map);
@Override @Override
default <T1> LinkedList<T1> pure(T1 t) { @Contract(pure = true, value = "_ -> new")
default <T1> @NotNull LinkedList<T1> pure(@NotNull T1 t) {
return of(t); return of(t);
} }
@Override @Override
<U> LinkedList<U> map(Function<T, U> map); @Contract(pure = true, value = "_ -> new")
<U> @NotNull LinkedList<U> map(@NotNull Function<T, U> map);
@Override @Override
default <T1> LinkedList<T1> identity() { @Contract(pure = true, value = "-> new")
default <T1> @NotNull LinkedList<T1> identity() {
return empty(); return empty();
} }
@Contract(pure = true, value = "-> new")
default Maybe<T> head() { default Maybe<T> head() {
return get(0); return get(0);
} }
LinkedList<T> tail(); LinkedList<T> tail();
@Contract(pure = true)
int length(); int length();
@Contract(pure = true)
Maybe<T> get(int index); Maybe<T> get(int index);
@Contract(pure = true, value = "_ -> new")
LinkedList<T> add(T value); LinkedList<T> add(T value);
default LinkedList<T> prepend(T value) { @NotNull
return new Cons<>(value, this); @Contract(pure = true, value = "_ -> new")
default LinkedList<T> prepend(@NotNull T value) {
return new Cons<>(Objects.requireNonNull(value), this);
} }
@Contract(mutates = "param")
<C extends Collection<T>> C toCollection(C collection); <C extends Collection<T>> C toCollection(C collection);
@NotNull
@Contract(pure = true, value = "-> new")
default List<T> toList() { default List<T> toList() {
return toCollection(new ArrayList<>()); return toCollection(new ArrayList<>());
} }
@NotNull
@Contract(pure = true, value = "-> new")
default Set<T> toSet() { default Set<T> toSet() {
return toCollection(new HashSet<>()); return toCollection(new HashSet<>());
} }
@Override @Override
LinkedList<T> multiply(Monoid<T, LinkedList<?>> t); @NotNull
LinkedList<T> multiply(@NotNull Monoid<T, LinkedList<?>> t);
static <T> LinkedList<T> of(T value) { static <T> LinkedList<T> of(T value) {
return new Cons<>(value, empty()); return new Cons<>(value, empty());
@@ -68,12 +90,12 @@ public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T,
record Cons<T>(T value, LinkedList<T> tail) implements LinkedList<T> { record Cons<T>(T value, LinkedList<T> tail) implements LinkedList<T> {
@Override @Override
public <T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map) { public <T2> @NotNull LinkedList<T2> bind(@NotNull Function<T, Monad<T2, LinkedList<?>>> map) {
return ((LinkedList<T2>) map.apply(value)).multiply(tail.bind(map)); return ((LinkedList<T2>) map.apply(value)).multiply(tail.bind(map));
} }
@Override @Override
public <U> LinkedList<U> map(Function<T, U> map) { public <U> @NotNull LinkedList<U> map(@NotNull Function<T, U> map) {
return new Cons<>(map.apply(value), tail.map(map)); return new Cons<>(map.apply(value), tail.map(map));
} }
@@ -101,7 +123,7 @@ public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T,
} }
@Override @Override
public LinkedList<T> multiply(Monoid<T, LinkedList<?>> t) { public @NotNull LinkedList<T> multiply(@NotNull Monoid<T, LinkedList<?>> t) {
return new Cons<>(value, tail.multiply(t)); return new Cons<>(value, tail.multiply(t));
} }
} }
@@ -111,13 +133,13 @@ public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T,
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map) { public <T2> @NotNull LinkedList<T2> bind(@NotNull Function<T, Monad<T2, LinkedList<?>>> map) {
return (LinkedList<T2>) this; return (LinkedList<T2>) this;
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U> LinkedList<U> map(Function<T, U> map) { public <U> @NotNull LinkedList<U> map(@NotNull Function<T, U> map) {
return (LinkedList<U>) this; return (LinkedList<U>) this;
} }
@@ -147,7 +169,7 @@ public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T,
} }
@Override @Override
public LinkedList<T> multiply(Monoid<T, LinkedList<?>> t) { public @NotNull LinkedList<T> multiply(@NotNull Monoid<T, LinkedList<?>> t) {
return (LinkedList<T>) t; return (LinkedList<T>) t;
} }
} }
@@ -2,9 +2,14 @@ package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.kinds.K; import com.dfsek.terra.api.util.generic.kinds.K;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public interface Monoid<T, M extends Monoid<?, M>> extends K<M, T>{
<T1> Monoid<T1, M> identity();
Monoid<T, M> multiply(Monoid<T, M> t); public interface Monoid<T, M extends Monoid<?, M>> extends K<M, T> {
@Contract(pure = true, value = "-> new")
<T1> @NotNull Monoid<T1, M> identity();
@Contract(pure = true, value = "_ -> new")
@NotNull Monoid<T, M> multiply(@NotNull Monoid<T, M> t);
} }
@@ -17,38 +17,52 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L, R, Either<?, ?>> { public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L, R, Either<?, ?>> {
default Either<L, R> ifLeft(Consumer<L> action) { static <T> T collapse(Either<T, T> either) {
return either.collect(Function.identity(), Function.identity());
}
@SuppressWarnings("unchecked")
static <T, L> Either<L, T> toEither(Optional<T> o, L de) {
return (Either<L, T>) o.map(Either::right).orElseGet(() -> left(de));
}
@NotNull
@Contract("_ -> this")
default Either<L, R> ifLeft(@NotNull Consumer<L> action) {
return mapLeft(FunctionUtils.lift(action)); return mapLeft(FunctionUtils.lift(action));
} }
default Either<L, R> ifRight(Consumer<R> action) { @NotNull
@Contract("_ -> this")
default Either<L, R> ifRight(@NotNull Consumer<R> action) {
return mapRight(FunctionUtils.lift(action)); return mapRight(FunctionUtils.lift(action));
} }
// Either is a functor in its right parameter. // Either is a functor in its right parameter.
@Override @Override
default <U> Either<L, U> map(Function<R, U> map) { default <U> @NotNull Either<L, U> map(@NotNull Function<R, U> map) {
return mapRight(map); return mapRight(map);
} }
@Override @Override
default <T1> Either<?, T1> pure(T1 t) { default <T1> @NotNull Either<?, T1> pure(@NotNull T1 t) {
return right(t); return right(t);
} }
@Override @Override
<T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map); <T2> @NotNull Either<L, T2> bind(@NotNull Function<R, Monad<T2, Either<?, ?>>> map);
@Override @Override
<L1> Either<L1, R> mapLeft(Function<L, L1> f); <L1> @NotNull Either<L1, R> mapLeft(@NotNull Function<L, L1> f);
@Override @Override
<R1> Either<L, R1> mapRight(Function<R, R1> f); <R1> @NotNull Either<L, R1> mapRight(@NotNull Function<R, R1> f);
Maybe<L> getLeft(); Maybe<L> getLeft();
@@ -93,18 +107,18 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) { public <T2> @NotNull Either<L, T2> bind(@NotNull Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) this; return (Either<L, T2>) this;
} }
@Override @Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) { public <L1> @NotNull Either<L1, R> mapLeft(@NotNull Function<L, L1> f) {
return new Left<>(f.apply(value)); return new Left<>(f.apply(value));
} }
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
@Override @Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) { public <R1> @NotNull Either<L, R1> mapRight(@NotNull Function<R, R1> f) {
return (Either<L, R1>) this; return (Either<L, R1>) this;
} }
@@ -142,18 +156,18 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
record Right<L, R>(R value) implements Either<L, R> { record Right<L, R>(R value) implements Either<L, R> {
@Override @Override
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) { public <T2> @NotNull Either<L, T2> bind(@NotNull Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) map.apply(value); return (Either<L, T2>) map.apply(value);
} }
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
@Override @Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) { public <L1> @NotNull Either<L1, R> mapLeft(@NotNull Function<L, L1> f) {
return (Either<L1, R>) this; return (Either<L1, R>) this;
} }
@Override @Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) { public <R1> @NotNull Either<L, R1> mapRight(@NotNull Function<R, R1> f) {
return new Right<>(f.apply(value)); return new Right<>(f.apply(value));
} }
@@ -3,6 +3,8 @@ package com.dfsek.terra.api.util.generic.data.types;
import com.dfsek.terra.api.util.generic.control.Monad; import com.dfsek.terra.api.util.generic.control.Monad;
import com.dfsek.terra.api.util.generic.data.LinkedList; import com.dfsek.terra.api.util.generic.data.LinkedList;
import org.jetbrains.annotations.NotNull;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -14,12 +16,12 @@ import java.util.stream.Stream;
public sealed interface Maybe<T> extends Monad<T, Maybe<?>> { public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
@Override @Override
default <T1> Maybe<T1> pure(T1 t) { default <T1> @NotNull Maybe<T1> pure(@NotNull T1 t) {
return just(t); return just(t);
} }
@Override @Override
<T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map); <T2> @NotNull Maybe<T2> bind(@NotNull Function<T, Monad<T2, Maybe<?>>> map);
Optional<T> toOptional(); Optional<T> toOptional();
@@ -30,7 +32,7 @@ public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
boolean isJust(); boolean isJust();
@Override @Override
<U> Maybe<U> map(Function<T, U> map); <U> @NotNull Maybe<U> map(@NotNull Function<T, U> map);
default T get(T def) { default T get(T def) {
return get(() -> def); return get(() -> def);
@@ -137,7 +139,7 @@ public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
} }
@Override @Override
public <U> Maybe<U> map(Function<T, U> map) { public <U> @NotNull Maybe<U> map(@NotNull Function<T, U> map) {
return just(map.apply(value)); return just(map.apply(value));
} }
@@ -147,7 +149,7 @@ public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
} }
@Override @Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) { public <T2> @NotNull Maybe<T2> bind(@NotNull Function<T, Monad<T2, Maybe<?>>> map) {
return (Maybe<T2>) map.apply(value); return (Maybe<T2>) map.apply(value);
} }
} }
@@ -155,7 +157,7 @@ public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
record Nothing<T>() implements Maybe<T> { record Nothing<T>() implements Maybe<T> {
@Override @Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) { public <T2> @NotNull Maybe<T2> bind(@NotNull Function<T, Monad<T2, Maybe<?>>> map) {
return nothing(); return nothing();
} }
@@ -181,7 +183,7 @@ public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U> Maybe<U> map(Function<T, U> map) { public <U> @NotNull Maybe<U> map(@NotNull Function<T, U> map) {
return (Maybe<U>) this; return (Maybe<U>) this;
} }
@@ -21,11 +21,11 @@ import java.util.function.Predicate;
public record Pair<L, R>(L left, R right) implements BiFunctor<L, R, Pair<?, ?>> { public record Pair<L, R>(L left, R right) implements BiFunctor<L, R, Pair<?, ?>> {
private static final Pair<?, ?> NULL = new Pair<>(null, null); private static final Pair<?, ?> NULL = new Pair<>(null, null);
public <T> Pair<T, R> mapLeft(Function<L, T> function) { public <T> @NotNull Pair<T, R> mapLeft(@NotNull Function<L, T> function) {
return of(function.apply(left), right); return of(function.apply(left), right);
} }
public <T> Pair<L, T> mapRight(Function<R, T> function) { public <T> @NotNull Pair<L, T> mapRight(@NotNull Function<R, T> function) {
return of(left, function.apply(right)); return of(left, function.apply(right));
} }