com.jnape.palatable.lambda.adt.hlist.Index Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lambda Show documentation
Show all versions of lambda Show documentation
Functional patterns for Java
package com.jnape.palatable.lambda.adt.hlist;
import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
/**
* HList indexes representing a value at arbitrary depth in some compatible HList. HList compatibility requires
* identical element types up to and including the target element, but thereafter is unconstrained in length and element
* type.
*
* @param the target element type
* @param type of compatible HList
*/
public abstract class Index> {
private Index() {
}
/**
* Nest this index deeper by one element.
*
* @param the type of the preceding element
* @return an index at the same Target, nested one level deep
*/
public final Index> after() {
return new N<>(this);
}
/**
* Retrieve the value at this index in hList.
*
* @param hList the hList
* @return the value at this index
*/
public abstract Target get(TargetList hList);
/**
* Set a new value of the same type at this index in an {@link HList}.
*
* @param newElement the new value
* @param hList the HList
* @param the inferred tail type of the HList
* @return the updated HList
*/
public abstract L set(Target newElement, L hList);
/**
* Create a root index for a head value of type Target
.
*
* @param the type of the value to get
* @return the root index
*/
public static Index> index() {
return Z.instance();
}
private static final class Z extends Index> {
private static final Z> INSTANCE = new Z<>();
@Override
public Target get(HCons hList) {
return hList.head();
}
@Override
@SuppressWarnings("unchecked")
public > L set(Target newElement, L hList) {
return (L) hList.tail().cons(newElement);
}
@SuppressWarnings("unchecked")
public static Z instance() {
return (Z) INSTANCE;
}
}
private static final class N, PreviousIndex extends Index> extends Index> {
private final PreviousIndex previousIndex;
private N(PreviousIndex previousIndex) {
this.previousIndex = previousIndex;
}
@Override
public Target get(HCons hList) {
return previousIndex.get(hList.tail());
}
@Override
@SuppressWarnings("unchecked")
public > L set(Target newElement, L hList) {
return (L) previousIndex.set(newElement, hList.tail()).cons(hList.head());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy