com.github.tonivade.purefun.generic.HList Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2020, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.generic;
import com.github.tonivade.purefun.Equal;
import com.github.tonivade.purefun.Sealed;
import com.github.tonivade.purefun.Tuple1;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Tuple3;
import com.github.tonivade.purefun.Tuple4;
import com.github.tonivade.purefun.Tuple5;
import com.github.tonivade.purefun.type.Option;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
@Sealed
public interface HList> {
int size();
HCons prepend(E element);
Option find(Class extends E> clazz);
HListModule getModule();
default boolean isEmpty() {
return size() == 0;
}
static HNil empty() {
return HNil.INSTANCE;
}
static > HCons cons(E element, L list) {
return new HCons<>(element, list);
}
static HCons of(A element) {
return empty().prepend(element);
}
static HCons> of(A element1, B element2) {
return empty().prepend(element2).prepend(element1);
}
static HCons>> of(A element1, B element2, C element3) {
return empty().prepend(element3).prepend(element2).prepend(element1);
}
static HCons>>> of(A element1,
B element2,
C element3,
D element4) {
return empty().prepend(element4).prepend(element3).prepend(element2).prepend(element1);
}
static HCons>>>> of(A element1,
B element2,
C element3,
D element4,
E element5) {
return empty().prepend(element5).prepend(element4).prepend(element3).prepend(element2).prepend(element1);
}
static HCons from(Tuple1 tuple) {
return tuple.applyTo(HList::of);
}
static HCons> from(Tuple2 tuple) {
return tuple.applyTo(HList::of);
}
static HCons>> from(Tuple3 tuple) {
return tuple.applyTo(HList::of);
}
static HCons>>> from(Tuple4 tuple) {
return tuple.applyTo(HList::of);
}
static HCons>>>> from(Tuple5 tuple) {
return tuple.applyTo(HList::of);
}
final class HNil implements HList {
private static final HNil INSTANCE = new HNil();
private HNil() {}
@Override
public int size() {
return 0;
}
@Override
public HCons prepend(E element) {
return cons(element, this);
}
@Override
public Option find(Class extends E> clazz) {
return Option.none();
}
@Override
public HListModule getModule() {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "HNil";
}
}
final class HCons> implements HList> {
private static final Equal> EQUAL = Equal.>of()
.comparing(HCons::head)
.comparing(HCons::tail);
private final H head;
private final T tail;
private HCons(H head, T tail) {
this.head = requireNonNull(head);
this.tail = requireNonNull(tail);
}
public H head() {
return head;
}
public T tail() {
return tail;
}
@Override
public int size() {
return 1 + tail.size();
}
@Override
public HCons> prepend(E element) {
return cons(element, this);
}
@Override
public Option find(Class extends E> clazz) {
if (clazz.isInstance(head)) {
return Option.some(clazz.cast(head));
}
return tail.find(clazz);
}
@Override
public HListModule getModule() {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return Objects.hash(head, tail);
}
@Override
public boolean equals(Object obj) {
return EQUAL.applyTo(this, obj);
}
@Override
public String toString() {
return "HCons(" + head + "," + tail + ")";
}
}
}
interface HListModule {}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy