
fj.data.hlist.HPre Maven / Gradle / Ivy
package fj.data.hlist;
import fj.Show;
/**
* A basic prelude of values lifted into the type system.
*/
@SuppressWarnings({"ALL"})
public final class HPre {
private HPre() {
throw new UnsupportedOperationException();
}
/**
* A type-level Boolean
*/
public static class HBool {
private HBool() {
}
}
/**
* Boolean true
*/
public static class HTrue extends HBool {
private HTrue() {
}
}
/**
* Boolean false
*/
public static class HFalse extends HBool {
private HFalse() {
}
}
private static final HTrue hTrue = new HTrue();
private static final HFalse hFalse = new HFalse();
/**
* Returns a boolean value whose type represents truth.
*
* @return a boolean value whose type represents truth.
*/
public static HTrue hTrue() {
return hTrue;
}
/**
* Returns a boolean value whose type represents falsehood.
*
* @return a boolean value whose type represents falsehood.
*/
public static HFalse hFalse() {
return hFalse;
}
/**
* Type-level boolean conjunction. A value of this type represents evidence that {@code AB -> C}
*
* @param A boolean
* @param A boolean
* @param The logical implication of A and B
*/
public static final class HAnd {
private final C v;
private HAnd(final C v) {
this.v = v;
}
public C v() {
return v;
}
public static HAnd hAnd(final HFalse a, final HFalse b) {
return new HAnd(hFalse());
}
public static HAnd hAnd(final HTrue a, final HFalse b) {
return new HAnd(hFalse());
}
public static HAnd hAnd(final HFalse a, final HTrue b) {
return new HAnd(hFalse());
}
public static HAnd hAnd(final HTrue a, final HTrue b) {
return new HAnd(hTrue());
}
}
/**
* Type-level boolean disjunction. A value of this type represents evidence that {@code A+B -> C}
*
* @param A boolean
* @param A boolean
* @param The logical implication of A or B
*/
public static final class HOr {
private final C v;
private HOr(final C v) {
this.v = v;
}
public C v() {
return v;
}
public static HOr hOr(final HFalse a, final HFalse b) {
return new HOr(hFalse());
}
public static HOr hOr(final HTrue a, final HFalse b) {
return new HOr(hTrue());
}
public static HOr hOr(final HFalse a, final HTrue b) {
return new HOr(hTrue());
}
public static HOr hOr(final HTrue a, final HTrue b) {
return new HOr(hTrue());
}
}
/**
* A type-level conditional. The type of the last parameter is implied by the first three.
*
* @param A boolean
* @param The type of Z if T is true.
* @param The type of Z if T is false.
* @param A type that is either X or Z, depending on T.
*/
public static final class HCond {
private HCond(final Z z) {
this.z = z;
}
private final Z z;
public Z v() {
return z;
}
public static HCond hCond(final HFalse t, final X x, final Y y) {
return new HCond(y);
}
public static HCond hCond(final HTrue t, final X x, final Y y) {
return new HCond(x);
}
}
/**
* Type-level natural numbers.
*/
public abstract static class HNat> {
public abstract Show show();
public abstract Integer toInteger();
public static HZero hZero() {
return new HZero();
}
public static > HSucc hSucc(final N n) {
return new HSucc(n);
}
public static > N hPred(final HSucc n) {
return n.pred;
}
}
/**
* Type-level zero
*/
public static final class HZero extends HNat {
private HZero() {
}
public Show show() {
return Show.showS(hZero -> "HZero");
}
public Integer toInteger() {
return 0;
}
}
/**
* A natural number N + 1
*
* @param The predecessor of this number.
*/
public static final class HSucc> extends HNat> {
private HSucc(final N n) {
pred = n;
}
private final N pred;
public Show> show() {
return Show.showS(s -> "HSucc (" + s.show().showS(s) + ')');
}
public Integer toInteger() {
return 1 + pred.toInteger();
}
}
/**
* Type-level equality. Represents evidence for X and Y being equal, or counterevidence against.
*/
public static final class HEq {
private final B v;
private HEq(final B v) {
this.v = v;
}
public B v() {
return v;
}
/**
* Zero is equal to itself.
*
* @param a Zero
* @param b Zero
* @return Equality for Zero
*/
public static HEq eq(final HZero a, final HZero b) {
return new HEq(hTrue());
}
/**
* Zero is not equal to anything other than zero.
*/
public static > HEq, HFalse> eq(final HZero a, final HSucc b) {
return new HEq, HFalse>(hFalse());
}
/**
* Zero is not equal to anything other than zero.
*/
public static > HEq, HZero, HFalse> eq(final HSucc a, final HZero b) {
return new HEq, HZero, HFalse>(hFalse());
}
/**
* A number is equal to another if their predecessors are equal.
*/
public static , NN extends HNat, B extends HBool, E extends HEq>
HEq, HSucc, B> eq(final HSucc a, final HSucc b, final E e) {
return new HEq, HSucc, B>(e.v());
}
}
/**
* Type-level integer arithmetic
*/
public static final class HAdd, B extends HNat, C extends HNat> {
private final C sum;
private HAdd(final C sum) {
this.sum = sum;
}
public C sum() {
return this.sum;
}
/**
* The sum of zero and any other number is that number.
*/
public static > HAdd, HSucc> add(final HZero a, final HSucc b) {
return new HAdd, HSucc>(b);
}
/**
* The sum of zero and any other number is that number.
*/
public static > HAdd, HZero, HSucc> add(final HSucc a, final HZero b) {
return new HAdd, HZero, HSucc>(a);
}
/**
* The sum of numbers a and b is one greater than the sum of b and the predecessor of a.
*/
public static , M extends HNat, R extends HNat, H extends HAdd, R>>
HAdd, HSucc, HSucc> add(final HSucc a, final HSucc b, final H h) {
return new HAdd, HSucc, HSucc>(HNat.hSucc(h.sum()));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy