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

fj.data.DList Maven / Gradle / Ivy

Go to download

Functional Java is an open source library that supports closures for the Java programming language

There is a newer version: 5.0
Show newest version
package fj.data;

import fj.F;
import fj.P;
import fj.control.Trampoline;

import java.util.Iterator;

import static fj.data.List.iterableList;

/**
 * Difference List. It converts left associative appends into right associative ones to improve performance.
 *
 * @version %build.number%
 */
public final class DList {
    private final F,Trampoline>> appendFn;
    
    private DList(final F,Trampoline>> appendFn) {
        this.appendFn = appendFn;
    }

    /**
     * Creates a DList from the function
     *
     * For alternatives functions to create a DList:
     * @see #iterableDList
     * @see #iteratorDList
     * @see #arrayDList
     */
    public static  DList dlist(final F,Trampoline>> f) {
        return new DList<>(f);
    }

    /**
     * Creates a DList from a List
     */
    public static  DList listDList(final List a) {
        return dlist((List tail) -> Trampoline.pure(a.append(tail)));
    }

    /**
     * Creates a DList from an Iterable
     */
    public static  DList iterableDList(final Iterable it) {
        return listDList(iterableList(it));
    }

    /**
     * Creates a DList from an Iterator
     */
    public static  DList iteratorDList(final Iterator it) {
        return iterableDList(() -> it);
    }

    /**
     * Creates a DList from an array
     */
    @SafeVarargs
    public static  DList arrayDList(final A...as) {
        return listDList(List.list(as));
    }

    /**
     * Concatenates all the internal Lists together that are held in
     * the DList's lambda's state to produce a List.
     * This is what converts the appending operation from left associative to right associative,
     * giving DList it's speed.
     * @return the final List
     */
    public List run() {
        return appendFn.f(List.nil()).run();
    }

    /**
     * Converts the DList to a standard java.util.List.
     */
    public java.util.List toJavaList() {
        return run().toJavaList();
    }
    
    /**
     * A empty DList.
     * @param 
     * @return a empty DList.
     */
    public static  DList nil() {
        return new DList<>(Trampoline.pure());
    }
    
    /**
     * Produces a DList with one element.
     * @param 
     * @param a the element in the DList.
     * @return a DList with one element.
     */
    public static  DList single(A a) {
        return new DList<>((List tail) -> Trampoline.pure(tail.cons(a)));
    }
    
    /**
     * Prepends a single element on the DList to produce a new DList.
     * @param a the element to append.
     * @return the new DList.
     */
    public DList cons(A a) {
        return single(a).append(this);
    }
    
    /**
     * Appends a single element on the end of the DList to produce a new DList.
     * @param a the element to append.
     * @return the new DList.
     */
    public DList snoc(A a) {
        return this.append(single(a));
    }
    
    /**
     * Appends two DLists together to produce a new DList.
     * @param other the other DList to append on the end of this one.
     * @return the new DList.
     */
    public DList append(DList other) {
        return new DList<>(kleisliTrampCompose(this.appendFn, other.appendFn));
    }
    
    private static  F> kleisliTrampCompose(F> bc, F> ab) {
        return (A a) -> ab.f(a).bind((B b) -> Trampoline.suspend(P.lazy(() -> bc.f(b))));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy