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

me.shaftesbury.utils.functional.LispList Maven / Gradle / Ivy

There is a newer version: 1.17
Show newest version
package me.shaftesbury.utils.functional;

/**
 * Created with IntelliJ IDEA.
 * User: Bob
 * Date: 26/11/13
 * Time: 20:57
 * To change this template use File | Settings | File Templates.
 */
public final class LispList
{
    public static interface List
    {
        T head();
        List tail();

        boolean isEmpty();
    }

    private static final List reverse(final List input, final List accumulator)
    {
        return input.isEmpty() ? accumulator : reverse(input.tail(),list(input.head(),accumulator));
    }

    public static final List reverse(final List input)
    {
        return reverse(input,(List)nil());
    }

    private static final List filter(final Func f, final List input, final List accumulator)
    {
        return input.isEmpty()
                ? accumulator
                : filter(f,input.tail(),f.apply(input.head())?list(input.head(), accumulator):accumulator);
    }

    public static final List filter(final Func f, final List input)
    {
        return reverse(filter(f, input, (List) nil()));
    }

    public static final List map(final Func f, final List input)
    {
        return input.isEmpty()
               ? (List)nil()
               : list(f.apply(input.head()),map(f,input.tail()));
    }

    public static final R fold(final Func2 f, final R initialValue, final List input)
    {
        return input.isEmpty()
                ? initialValue
                : fold(f,f.apply(initialValue,input.head()),input.tail());
    }
    public static final R foldRight(final Func2 f, final R initialValue, final List input)
    {
        return input.isEmpty()
                ? initialValue
                : f.apply(input.head(),foldRight(f,initialValue,input.tail()));
    }

    public static final class EmptyListHasNoHead extends RuntimeException {}
    public static final class EmptyListHasNoTail extends RuntimeException {}

    private static final LispList ll = new LispList();

    public final class NonEmptyList implements List
    {
        final private T _head;
        final private List _tail;

        NonEmptyList(final T head, final List tail)
        {
            _head = head;
            _tail = tail;
        }

        @Override
        public T head() {
            return _head;
        }

        @Override
        public List tail() {
            return _tail;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        public boolean equals(Object o)
        {
            if(o==null) return false;
            if(o instanceof NonEmptyList)
                return ((NonEmptyList)o).head().equals(head()) && ((NonEmptyList)o).tail().equals(tail());
            else return false;
        }

        public String toString()
        {
            return "( "+head()+", "+tail().toString()+" )";
        }
    }

    public static final List nil()
    {
        return new List(){
            @Override
            public T head() {
                throw new EmptyListHasNoHead();
            }

            @Override
            public List tail() {
                throw new EmptyListHasNoTail();
            }

            @Override
            public boolean isEmpty() {
                return true;
            }

            public boolean equals(Object o)
            {
                if(o==null) return false;
                return o instanceof List && ((List)o).isEmpty();
            }

            public String toString() { return "( )";}
        };
    }

    public static final List list(final T head, final List tail)
    {
        return ll.new NonEmptyList(head,tail);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy