add linkedlist

This commit is contained in:
dfsek
2026-01-01 20:09:06 -07:00
parent 8eb5a70d4d
commit eb6b3704d0
5 changed files with 334 additions and 188 deletions

View File

@@ -0,0 +1,143 @@
package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.control.Monad;
import com.dfsek.terra.api.util.generic.data.types.Maybe;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public sealed interface LinkedList<T> extends Monad<T, LinkedList<?>>, Monoid<T, LinkedList<?>> {
@Override
<T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map);
@Override
default <T1> LinkedList<T1> pure(T1 t) {
return new Cons<>(t, empty());
}
@Override
<U> LinkedList<U> map(Function<T, U> map);
@Override
default <T1> LinkedList<T1> identity() {
return empty();
}
default Maybe<T> head() {
return get(0);
}
int length();
Maybe<T> get(int index);
LinkedList<T> add(T value);
<C extends Collection<T>> C toCollection(C collection);
default List<T> toList() {
return toCollection(new ArrayList<>());
}
default Set<T> toSet() {
return toCollection(new HashSet<>());
}
@Override
LinkedList<T> multiply(Monoid<T, LinkedList<?>> t);
static <T> LinkedList<T> of(T value) {
return new Cons<>(value, empty());
}
@SuppressWarnings("unchecked")
static <T> Nil<T> empty() {
return (Nil<T>) Nil.INSTANCE;
}
record Cons<T>(T value, LinkedList<T> tail) implements LinkedList<T> {
@Override
public <T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map) {
return ((LinkedList<T2>) map.apply(value)).multiply(tail.bind(map));
}
@Override
public <U> LinkedList<U> map(Function<T, U> map) {
return new Cons<>(map.apply(value), tail.map(map));
}
@Override
public int length() {
return 1 + tail.length();
}
@Override
public Maybe<T> get(int index) {
if(index == 0) return Maybe.just(value);
if(index > 0) return Maybe.nothing();
return tail.get(index - 1);
}
@Override
public LinkedList<T> add(T value) {
return new Cons<>(value, tail.add(value));
}
@Override
public <C extends Collection<T>> C toCollection(C collection) {
collection.add(value);
return tail.toCollection(collection);
}
@Override
public LinkedList<T> multiply(Monoid<T, LinkedList<?>> t) {
return new Cons<>(value, tail.multiply(t));
}
}
record Nil<T>() implements LinkedList<T> {
private static final Nil<?> INSTANCE = new Nil<>();
@Override
@SuppressWarnings("unchecked")
public <T2> LinkedList<T2> bind(Function<T, Monad<T2, LinkedList<?>>> map) {
return (LinkedList<T2>) this;
}
@Override
@SuppressWarnings("unchecked")
public <U> LinkedList<U> map(Function<T, U> map) {
return (LinkedList<U>) this;
}
@Override
public int length() {
return 0;
}
@Override
public Maybe<T> get(int index) {
return Maybe.nothing();
}
@Override
public LinkedList<T> add(T value) {
return new Cons<>(value, empty());
}
@Override
public <C extends Collection<T>> C toCollection(C collection) {
return collection;
}
@Override
public LinkedList<T> multiply(Monoid<T, LinkedList<?>> t) {
return (LinkedList<T>) t;
}
}
}

View File

@@ -3,9 +3,8 @@ package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.kinds.K;
public interface Monoid<T, M extends Monoid<?, M>> extends Semigroup<T, M>, K<M, T>{
<T1, M1 extends Monoid<?, M1>> Monoid<T1, M1> identity();
public interface Monoid<T, M extends Monoid<?, M>> extends K<M, T>{
<T1> Monoid<T1, M> identity();
@Override
Monoid<T, M> multiply(M t);
Monoid<T, M> multiply(Monoid<T, M> t);
}

View File

@@ -1,8 +0,0 @@
package com.dfsek.terra.api.util.generic.data;
import com.dfsek.terra.api.util.generic.kinds.K;
public interface Semigroup<T, S extends Semigroup<?, S>> extends K<S, T> {
Semigroup<T, S> multiply(S t);
}

View File

@@ -21,7 +21,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
public 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) {
return mapLeft(FunctionUtils.lift(action));
}
@@ -77,115 +77,114 @@ public interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L, R, Ei
return mapLeft(left).collect(l -> FunctionUtils.sneakyThrow(l), Function.identity());
}
@SuppressWarnings({ "unchecked" })
@NotNull
@Contract("_ -> new")
static <L1, R1> Either<L1, R1> left(L1 left) {
record Left<L, R>(L value) implements Either<L, R> {
@Override
@SuppressWarnings("unchecked")
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) this;
}
@Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) {
return new Left<>(f.apply(value));
}
@SuppressWarnings({ "unchecked" })
@Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) {
return (Either<L, R1>) this;
}
@Override
public Maybe<L> getLeft() {
return Maybe.just(value);
}
@Override
public Maybe<R> getRight() {
return Maybe.nothing();
}
@Override
public boolean isLeft() {
return true;
}
@Override
public boolean isRight() {
return false;
}
@Override
public Either<R, L> flip() {
return right(value);
}
@Override
public <U> U collect(Function<L, U> left, Function<R, U> right) {
return left.apply(value);
}
}
return new Left<>(Objects.requireNonNull(left));
}
@SuppressWarnings({ "unchecked" })
@NotNull
@Contract("_ -> new")
static <L1, R1> Either<L1, R1> right(R1 right) {
record Right<L, R>(R value) implements Either<L, R> {
@Override
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) map.apply(value);
}
@SuppressWarnings({ "unchecked" })
@Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) {
return (Either<L1, R>) this;
}
@Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) {
return new Right<>(f.apply(value));
}
@Override
public Maybe<L> getLeft() {
return Maybe.nothing();
}
@Override
public Maybe<R> getRight() {
return Maybe.just(value);
}
@Override
public boolean isLeft() {
return false;
}
@Override
public boolean isRight() {
return true;
}
@Override
public Either<R, L> flip() {
return left(value);
}
@Override
public <U> U collect(Function<L, U> left, Function<R, U> right) {
return right.apply(value);
}
}
return new Right<>(Objects.requireNonNull(right));
}
record Left<L, R>(L value) implements Either<L, R> {
@Override
@SuppressWarnings("unchecked")
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) this;
}
@Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) {
return new Left<>(f.apply(value));
}
@SuppressWarnings({ "unchecked" })
@Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) {
return (Either<L, R1>) this;
}
@Override
public Maybe<L> getLeft() {
return Maybe.just(value);
}
@Override
public Maybe<R> getRight() {
return Maybe.nothing();
}
@Override
public boolean isLeft() {
return true;
}
@Override
public boolean isRight() {
return false;
}
@Override
public Either<R, L> flip() {
return right(value);
}
@Override
public <U> U collect(Function<L, U> left, Function<R, U> right) {
return left.apply(value);
}
}
record Right<L, R>(R value) implements Either<L, R> {
@Override
public <T2> Either<L, T2> bind(Function<R, Monad<T2, Either<?, ?>>> map) {
return (Either<L, T2>) map.apply(value);
}
@SuppressWarnings({ "unchecked" })
@Override
public <L1> Either<L1, R> mapLeft(Function<L, L1> f) {
return (Either<L1, R>) this;
}
@Override
public <R1> Either<L, R1> mapRight(Function<R, R1> f) {
return new Right<>(f.apply(value));
}
@Override
public Maybe<L> getLeft() {
return Maybe.nothing();
}
@Override
public Maybe<R> getRight() {
return Maybe.just(value);
}
@Override
public boolean isLeft() {
return false;
}
@Override
public boolean isRight() {
return true;
}
@Override
public Either<R, L> flip() {
return left(value);
}
@Override
public <U> U collect(Function<L, U> left, Function<R, U> right) {
return right.apply(value);
}
}
}

View File

@@ -1,6 +1,7 @@
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.data.LinkedList;
import java.util.NoSuchElementException;
import java.util.Optional;
@@ -11,7 +12,7 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
public interface Maybe<T> extends Monad<T, Maybe<?>> {
public sealed interface Maybe<T> extends Monad<T, Maybe<?>> {
@Override
default <T1> Maybe<T1> pure(T1 t) {
return just(t);
@@ -49,9 +50,20 @@ public interface Maybe<T> extends Monad<T, Maybe<?>> {
return this;
}
default Maybe<T> collapse(Runnable nothing, Consumer<T> just) {
return consume(just).ifNothing(nothing);
}
default LinkedList<T> toList() {
return map(LinkedList::of).get(LinkedList::empty);
}
/**
* Project a new value into this Maybe if it is Nothing.
* Effectively a bind operation over Nothing, treating it as a Void type.
* <p>
* Converse of {@link #bind}.
*/
Maybe<T> or(Supplier<Maybe<T>> or);
@@ -59,7 +71,6 @@ public interface Maybe<T> extends Monad<T, Maybe<?>> {
return or(() -> just(or.get()));
}
@Deprecated
default <X extends Throwable> T orThrow() {
return get(() -> { throw new NoSuchElementException("No value present."); });
@@ -73,7 +84,6 @@ public interface Maybe<T> extends Monad<T, Maybe<?>> {
throw e.get();
}
default Maybe<T> or(Maybe<T> or) {
return or(() -> or);
}
@@ -96,85 +106,88 @@ public interface Maybe<T> extends Monad<T, Maybe<?>> {
}
static <T1> Maybe<T1> just(T1 t) {
record Just<T>(T value) implements Maybe<T> {
@Override
public Optional<T> toOptional() {
return Optional.of(value);
}
@Override
public <L> Either<L, T> toEither(L l) {
return Either.right(value);
}
@Override
public T get(Supplier<T> def) {
return value;
}
@Override
public boolean isJust() {
return true;
}
@Override
public <U> Maybe<U> map(Function<T, U> map) {
return just(map.apply(value));
}
@Override
public Maybe<T> or(Supplier<Maybe<T>> or) {
return this;
}
@Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) {
return (Maybe<T2>) map.apply(value);
}
}
return new Just<>(t);
}
static <T1> Maybe<T1> nothing() {
record Nothing<T>() implements Maybe<T> {
@Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) {
return nothing();
}
@Override
public Optional<T> toOptional() {
return Optional.empty();
}
@Override
public <L> Either<L, T> toEither(L l) {
return Either.left(l);
}
@Override
public T get(Supplier<T> def) {
return def.get();
}
@Override
public boolean isJust() {
return false;
}
@Override
@SuppressWarnings("unchecked")
public <U> Maybe<U> map(Function<T, U> map) {
return (Maybe<U>) this;
}
@Override
public Maybe<T> or(Supplier<Maybe<T>> or) {
return or.get();
}
}
return new Nothing<>();
}
record Just<T>(T value) implements Maybe<T> {
@Override
public Optional<T> toOptional() {
return Optional.of(value);
}
@Override
public <L> Either<L, T> toEither(L l) {
return Either.right(value);
}
@Override
public T get(Supplier<T> def) {
return value;
}
@Override
public boolean isJust() {
return true;
}
@Override
public <U> Maybe<U> map(Function<T, U> map) {
return just(map.apply(value));
}
@Override
public Maybe<T> or(Supplier<Maybe<T>> or) {
return this;
}
@Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) {
return (Maybe<T2>) map.apply(value);
}
}
record Nothing<T>() implements Maybe<T> {
@Override
public <T2> Maybe<T2> bind(Function<T, Monad<T2, Maybe<?>>> map) {
return nothing();
}
@Override
public Optional<T> toOptional() {
return Optional.empty();
}
@Override
public <L> Either<L, T> toEither(L l) {
return Either.left(l);
}
@Override
public T get(Supplier<T> def) {
return def.get();
}
@Override
public boolean isJust() {
return false;
}
@Override
@SuppressWarnings("unchecked")
public <U> Maybe<U> map(Function<T, U> map) {
return (Maybe<U>) this;
}
@Override
public Maybe<T> or(Supplier<Maybe<T>> or) {
return or.get();
}
}
}