mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
add linkedlist
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user