import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
interface FunctionalField<FIELD extends Enum<?>> {
public Object untypedField(FIELD field);
@SuppressWarnings("unchecked")
public default <VALUE> VALUE field(FIELD field) {
return (VALUE) untypedField(field);
}
public static <FIELD extends Enum<FIELD>> Object throwOnUndefinedField(FIELD field) throws Error {
throw new InternalError(field + " is undefined");
}
}
@FunctionalInterface
interface Cell<ELEMENT> {
public <VALUE> VALUE select(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil);
public static <ELEMENT, VALUE> VALUE nil(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons,
Supplier<? extends VALUE> nil) {
return nil.get();
}
public default int size() {
return select(
(element, next) -> 1 + next.size(),
() -> 0
);
}
public default Cell<ELEMENT> first(int size) {
return Optional.of(size)
.<Cell<ELEMENT>>map(s -> select(
(element, next) -> s == 0
? nil()
: cons(element, next.first(s - 1))
,
Cell::nil
))
.orElseThrow(IllegalArgumentException::new)
;
}
public default <ELEMENT2> Cell<ELEMENT2> map(Function<? super ELEMENT, ? extends ELEMENT2> mapper) {
return select(
(element, next) -> Cell.cons(mapper.apply(element), next.map(mapper)),
Cell::nil
);
}
public default <ELEMENT2> Cell<ELEMENT2> flatMap(Function<? super ELEMENT, Cell<ELEMENT2>> mapper) {
return select(
(element, next) -> mapper
.apply(element)
.select(
Cell::cons,
() -> next.flatMap(mapper)
)
,
Cell::nil
);
}
public interface Cons<ELEMENT> {
public ELEMENT element();
public Cell<ELEMENT> next();
public default <VALUE> VALUE cons(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return cons.apply(element(), next());
}
public static <ELEMENT> Cons<ELEMENT> new_(ELEMENT element, Cell<ELEMENT> next) {
return $.$Cons.new_(element, next);
}
public enum $ {
;
@FunctionalInterface
private interface $Cons<ELEMENT> extends Cons<ELEMENT>, FunctionalField<$Cons.Field> {
public enum Field {
element,
next
}
@Override
public default ELEMENT element() {
return field(Field.element);
}
public default Cell<ELEMENT> next() {
return field(Field.next);
}
public static <ELEMENT> $Cons<ELEMENT> new_(ELEMENT element, Cell<ELEMENT> next) {
return field -> {
switch (field) {
case element: return element;
case next: return next;
default: return FunctionalField.throwOnUndefinedField(field);
}
};
}
}
}
}
public static <ELEMENT> Cell<ELEMENT> nil() {
return Cell::nil;
}
public static <ELEMENT> Cell<ELEMENT> cons(ELEMENT element, Cell<ELEMENT> next) {
Objects.requireNonNull(element);
Objects.requireNonNull(next);
return Cons.new_(element, next)::cons;
}
public static void main(String... arguments) {
System.out.println(nil() == nil());
Cell<Integer> cell =
cons(1, cons(2, cons(3, nil())))
;
System.out.println(cell.size() == 3);
System.out.println(cell.first(2).size() == 2);
}
}
public interface Main {
public static void main(String... arguments) {
Cell.main(arguments);
}
}
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
@FunctionalInterface
interface FunctionalField<FIELD extends Enum<?>> {
public Object untypedField(FIELD field);
@SuppressWarnings("unchecked")
public default <VALUE> VALUE field(FIELD field) {
return (VALUE) untypedField(field);
}
public static <FIELD extends Enum<FIELD>> Object throwOnUndefinedField(FIELD field) throws Error {
throw new InternalError(field + " is undefined");
}
}
@FunctionalInterface
interface $Cons<ELEMENT> extends Cons<ELEMENT>, FunctionalField<$Cons.Field> {
public enum Field {
element,
next,
implementation
}
@Override
public default ELEMENT element() {
return field(Field.element);
}
public default Cell<ELEMENT> next() {
return field(Field.next);
}
public default Implementation<ELEMENT> implementation() {
return field(Field.implementation);
}
public static <ELEMENT> $Cons<ELEMENT> new_(ELEMENT element, Cell<ELEMENT> next, Implementation<ELEMENT> implementation) {
return field -> {
switch (field) {
case element: return element;
case next: return next;
case implementation: return implementation;
default: return FunctionalField.throwOnUndefinedField(field);
}
};
}
}
interface Cons<ELEMENT> {
public ELEMENT element();
public Cell<ELEMENT> next();
public Implementation<ELEMENT> implementation();
@FunctionalInterface
public interface Implementation<ELEMENT> {
public <VALUE> VALUE select(ELEMENT element, Cell<ELEMENT> next, BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil);
}
public default <VALUE> VALUE cons(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return implementation().select(element(), next(), cons, nil);
}
public static <ELEMENT> Cons<ELEMENT> new_(ELEMENT element, Cell<ELEMENT> next, Implementation<ELEMENT> implementation) {
return $Cons.new_(element, next, implementation);
}
}
@FunctionalInterface
interface Cell<ELEMENT> {
public <VALUE> VALUE select(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil);
public default int size() {
return select(
(element, next) -> 1 + next.size(),
() -> 0
);
}
public default Cell<ELEMENT> first(int size) {
return Optional.of(size)
.<Cell<ELEMENT>>map(s -> select(
(element, next) -> s == 0
? nil()
: cons(element, next.first(s - 1))
,
Cell::nil
))
.orElseThrow(IllegalArgumentException::new)
;
}
public default <ELEMENT2> Cell<ELEMENT2> map(Function<? super ELEMENT, ? extends ELEMENT2> mapper) {
return select(
(element, next) -> Cell.cons(mapper.apply(element), next.map(mapper)),
Cell::nil
);
}
public default <ELEMENT2> Cell<ELEMENT2> flatMap(Function<? super ELEMENT, Cell<ELEMENT2>> mapper) {
return select(
(element, next) -> mapper
.apply(element)
.select(
Cell::cons,
() -> next.flatMap(mapper)
)
,
Cell::nil
);
}
public static <ELEMENT, VALUE> VALUE nil(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return nil.get();
}
public static <ELEMENT, VALUE> VALUE cons(ELEMENT element, Cell<ELEMENT> next, BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return cons.apply(element, next);
}
public static <ELEMENT> Cell<ELEMENT> nil() {
return Cell::nil;
}
public static <ELEMENT> Cell<ELEMENT> cons(ELEMENT element, Cell<ELEMENT> next) {
Stream.of(
element,
next
)
.forEach(Objects::requireNonNull)
;
return Cons.new_(
element,
next,
Cell::cons
)::cons;
}
public static void main(String... arguments) {
Cell<Integer> cell =
cons(1, cons(2, cons(3, nil())))
;
System.out.println(nil() == nil());
System.out.println(cell.size() == 3);
System.out.println(cell.first(2).size() == 2);
}
}
public interface Main {
public static void main(String... arguments) {
Cell.main(arguments);
}
}
import java.util.function.Function;
import java.util.stream.Stream;
@FunctionalInterface
interface Selector<TYPE> {
Object $get(Function<TYPE, Object> fun);
@SuppressWarnings("unchecked")
public default <VALUE> VALUE get(Function<TYPE, VALUE> fun) {
return (VALUE) $get(
(Function<TYPE, Object>) fun
);
}
public default TYPE from(Selector<TYPE> selector) {
throw new InternalError("Selector::from is not implemented.");
}
public default <VALUE> TYPE with(Function<TYPE, ? extends VALUE> fun, VALUE value) {
return from(f -> (f == fun)
? value
: get(f)
);
}
}
@FunctionalInterface
interface $Point extends Point, Selector<Point> {
public static final Function<Point, Integer> X = Point::getX;
public static final Function<Point, Integer> Y = Point::getY;
@Override
public default int getX() {
return get(X);
}
@Override
public default int getY() {
return get(Y);
}
@Override
public default Point withX(int x) {
return with(X, x);
}
@Override
public default Point withY(int y) {
return with(Y, y);
}
@Override
public default Point from(Selector<Point> selector) {
return ($Point) selector::get;
}
public static $Point none() {
return f -> {
throw new IllegalStateException("no value");
};
}
}
interface Point {
public int getX();
public int getY();
public Point withX(int x);
public Point withY(int y);
public static Point none() {
return $Point.none();
}
public static void main(String[] args) {
Point point = none()
.withX(3)
.withY(4)
;
Stream.of(
point.getX(),
point.getY()
)
.forEach(System.out::println)
;
}
}
public interface Main {
public static void main(String... arguments) {
Point.main(arguments);
}
}
import java.util.function.Function;
import java.util.stream.Stream;
@FunctionalInterface
interface Selector<TYPE> {
Object $get(Function<TYPE, Object> function);
@SuppressWarnings("unchecked")
public default <VALUE> VALUE get(Function<TYPE, VALUE> function) {
return (VALUE) $get(
(Function<TYPE, Object>) function
);
}
public default TYPE from(Selector<TYPE> selector) {
throw new InternalError("Selector::from is not implemented.");
}
public default <VALUE> TYPE with(Function<TYPE, ? extends VALUE> function, VALUE value) {
return from(f -> (f == function)
? value
: get(f)
);
}
public static <TYPE> Object none(Function<TYPE, Object> function) {
throw new IllegalStateException("no value");
}
}
@FunctionalInterface
interface $Point extends Point, Selector<Point> {
public static final Function<Point, Integer> X = Point::getX;
public static final Function<Point, Integer> Y = Point::getY;
@Override
public default int getX() {
return get(X);
}
@Override
public default int getY() {
return get(Y);
}
@Override
public default Point withX(int x) {
return with(X, x);
}
@Override
public default Point withY(int y) {
return with(Y, y);
}
@Override
public default Point from(Selector<Point> selector) {
return ($Point) selector::get;
}
public static $Point none() {
return Selector::none;
}
}
interface Point {
public int getX();
public int getY();
public Point withX(int x);
public Point withY(int y);
public static Point none() {
return $Point.none();
}
public static void main(String[] args) {
Point point = none()
.withX(3)
.withY(4)
;
Stream.of(
point.getX(),
point.getY()
)
.forEach(System.out::println)
;
}
}
public interface Main {
public static void main(String... arguments) {
Point.main(arguments);
}
}
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
@FunctionalInterface
interface Selector<TYPE> {
Object $get(Function<TYPE, Object> function);
@SuppressWarnings("unchecked")
public default <VALUE> VALUE get(Function<TYPE, VALUE> function) {
return (VALUE) $get(
(Function<TYPE, Object>) function
);
}
public default TYPE from(Selector<TYPE> selector) {
throw new InternalError("Selector::from is not implemented.");
}
public default <VALUE> TYPE with(Function<TYPE, ? extends VALUE> function, VALUE value) {
return from(f -> (f == function)
? value
: get(f)
);
}
public static <TYPE> Object none(Function<TYPE, Object> function) {
throw new IllegalStateException("no value");
}
}
interface Cons<ELEMENT> {
public ELEMENT getElement();
public Cell<ELEMENT> getNext();
public Implementation<ELEMENT> getImplementation();
public Cons<ELEMENT> withElement(ELEMENT element);
public Cons<ELEMENT> withNext(Cell<ELEMENT> next);
public Cons<ELEMENT> withImplementation(Implementation<ELEMENT> implementation);
@FunctionalInterface
public interface Implementation<ELEMENT> {
public <VALUE> VALUE select(ELEMENT element, Cell<ELEMENT> next, BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil);
}
public default <VALUE> VALUE cons(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return getImplementation()
.select(
getElement(),
getNext(),
cons,
nil
)
;
}
public static <ELEMENT> Cons<ELEMENT> none() {
return $Cons.none();
}
}
@FunctionalInterface
interface $Cons<ELEMENT> extends Cons<ELEMENT>, Selector<Cons<ELEMENT>> {
public static <ELEMENT> Function<Cons<ELEMENT>, ELEMENT> Element() {
return Cons::getElement;
}
public static <ELEMENT> Function<Cons<ELEMENT>, Cell<ELEMENT>> Next() {
return Cons::getNext;
}
public static <ELEMENT> Function<Cons<ELEMENT>, Implementation<ELEMENT>> Implementation() {
return Cons::getImplementation;
}
@Override
public default ELEMENT getElement() {
return get(Element());
}
@Override
public default Cell<ELEMENT> getNext() {
return get(Next());
}
@Override
public default Implementation<ELEMENT> getImplementation() {
return get(Implementation());
}
@Override
public default Cons<ELEMENT> withElement(ELEMENT element) {
return with(Element(), element);
}
@Override
public default Cons<ELEMENT> withNext(Cell<ELEMENT> next) {
return with(Next(), next);
}
@Override
public default Cons<ELEMENT> withImplementation(Implementation<ELEMENT> implementation) {
return with(Implementation(), implementation);
}
@Override
public default Cons<ELEMENT> from(Selector<Cons<ELEMENT>> selector) {
return ($Cons<ELEMENT>) selector::get;
}
public static <ELEMENT> $Cons<ELEMENT> none() {
return Selector::none;
}
}
@FunctionalInterface
interface Cell<ELEMENT> {
public <VALUE> VALUE select(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil);
public default int size() {
return select(
(element, next) -> 1 + next.size(),
() -> 0
);
}
public default Cell<ELEMENT> first(int size) {
return Optional.of(size)
.<Cell<ELEMENT>>map(s -> select(
(element, next) -> s == 0
? nil()
: cons(element, next.first(s - 1))
,
Cell::nil
))
.orElseThrow(IllegalArgumentException::new)
;
}
public default <ELEMENT2> Cell<ELEMENT2> map(Function<? super ELEMENT, ? extends ELEMENT2> mapper) {
return select(
(element, next) -> Cell.cons(mapper.apply(element), next.map(mapper)),
Cell::nil
);
}
public default <ELEMENT2> Cell<ELEMENT2> flatMap(Function<? super ELEMENT, Cell<ELEMENT2>> mapper) {
return select(
(element, next) -> mapper
.apply(element)
.select(
Cell::cons,
() -> next.flatMap(mapper)
)
,
Cell::nil
);
}
public static <ELEMENT, VALUE> VALUE nil(BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return nil.get();
}
public static <ELEMENT, VALUE> VALUE cons(ELEMENT element, Cell<ELEMENT> next, BiFunction<? super ELEMENT, Cell<ELEMENT>, ? extends VALUE> cons, Supplier<? extends VALUE> nil) {
return cons.apply(element, next);
}
public static <ELEMENT> Cell<ELEMENT> nil() {
return Cell::nil;
}
public static <ELEMENT> Cell<ELEMENT> cons(ELEMENT element, Cell<ELEMENT> next) {
Stream.of(
element,
next
)
.forEach(Objects::requireNonNull)
;
return Cons.<ELEMENT>none()
.withElement(element)
.withNext(next)
.withImplementation(Cell::cons)
::cons
;
}
public static void main(String... arguments) {
Cell<Integer> cell =
cons(1, cons(2, cons(3, nil())))
;
System.out.println(nil() == nil());
System.out.println(cell.size() == 3);
System.out.println(cell.first(2).size() == 2);
}
}
public interface Main {
public static void main(String... arguments) {
Cell.main(arguments);
}
}