me.shaftesbury.utils.functional.LispList Maven / Gradle / Ivy
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 List cons(final T t, final List l) { return list(t,l); }
public static final T car(final List l) { return l.head(); }
public static final List cdr(final List l) { return l.tail(); }
public static final T cadr(final List l) { return car(cdr(l)); }
public static final List compose(final T t1, final T t2) { return list(t1, list(t2, (List)nil())); }
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