All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jnape.palatable.lambda.adt.hlist.Index Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
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