/* * xtc - The eXTensible Compiler * Copyright (C) 2007 Robert Grimm, New York University * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package xtc.util; /** * Function definitions. * * @author Laune Harris * @author Robert Grimm * @version $Revision: 1.5 $ */ public class Function { /** Hidden constructor. */ private Function() { /* Nothing to do. */ } /** A function with no arguments. */ public static interface F0<R> { R apply(); } /** A function with one argument. */ public static interface F1<R,A> { R apply(A a); } /** A function with two arguments. */ public static interface F2<R,A,B> { R apply(A a,B b); } /** A function with three arguments. */ public static interface F3<R,A,B,C> { R apply(A a,B b,C c); } /** A function with four arguments. */ public static interface F4<R,A,B,C,D> { R apply(A a,B b,C c,D d); } /** A function with five arguments. */ public static interface F5<R,A,B,C,D,E> { R apply(A a,B b,C c,D d,E e); } /** A function with six arguments. */ public static interface F6<R,A,B,C,D,E,F> { R apply(A a,B b,C c,D d,E e,F f); } /** A function with seven arguments. */ public static interface F7<R,A,B,C,D,E,F,G> { R apply(A a,B b,C c,D d,E e,F f,G g); } /** A function with eight arguments. */ public static interface F8<R,A,B,C,D,E,F,G,H> { R apply(A a,B b,C c,D d,E e,F f,G g,H h); } /** A function with nine arguments. */ public static interface F9<R,A,B,C,D,E,F,G,H> { R apply(A a,B b,C c,D d,E e,F f,G g,H h); } /** A function with ten arguments. */ public static interface F10<R,A,B,C,D,E,F,G,H,I> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i); } /** A function with eleven arguments. */ public static interface F11<R,A,B,C,D,E,F,G,H,I,J> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i,J j); } /** A function with twelve arguments. */ public static interface F12<R,A,B,C,D,E,F,G,H,I,J,K> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k); } /** A function with thirteen arguments. */ public static interface F13<R,A,B,C,D,E,F,G,H,I,J,K,L> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l); } /** A function with fourteen arguments. */ public static interface F14<R,A,B,C,D,E,F,G,H,I,J,K,L,M> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m); } /** A function with fifteen arguments. */ public static interface F15<R,A,B,C,D,E,F,G,H,I,J,K,L,M,N> { R apply(A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m,N n); } /** * Iterate the specified function over the specified list. * * @param function The function. * @param list The list. */ public static <T, U> void iterate(Function.F1<U,? super T> function, Pair<T> list) { while (Pair.EMPTY != list) { function.apply(list.head); list = list.tail; } } /** * Map the specified function over the specified list. Note that * the implementation does not recurse. * * @param function The function. * @param list The list. * @return The result of mapping the function. */ public static <T, U> Pair<U> map(Function.F1<U,? super T> function, Pair<T> list) { if (Pair.EMPTY == list) return Pair.empty(); Pair<U> result = new Pair<U>(function.apply(list.head)); Pair<U> cursor = result; while (Pair.EMPTY != list.tail) { list = list.tail; cursor.tail = new Pair<U>(function.apply(list.head)); cursor = cursor.tail; } return result; } /** * Fold the specified list with the specified function. This method * successively applies the specified function to each of the list's * elements and a running result, which is initialized to the * specified seed. * * @param function The function. * @param seed The seed value. * @param list The list. * @return The folded value. */ public static <T, U> U foldl(Function.F2<U,? super T,U> function, U seed, Pair<T> list) { while (Pair.EMPTY != list) { seed = function.apply(list.head, seed); list = list.tail; } return seed; } /** * Determine whether the specified list contains only elements * matching the specified predicate. * * @param pred The predicate. * @param list The list. * @return <code>true</code> if the list contains only matching * elements. */ public static <T> boolean matchesAll(Function.F1<Boolean,? super T> pred, Pair<T> list) { while (Pair.EMPTY != list) { if (! pred.apply(list.head)) return false; list = list.tail; } return true; } /** * Determine whether the specified list contains an element matching * the specified predicate. * * @param pred The predicate. * @param list The list. * @return <code>true</code> if the list contains at least one * matching element. */ public static <T> boolean matchesOne(Function.F1<Boolean,? super T> pred, Pair<T> list) { while (Pair.EMPTY != list) { if (pred.apply(list.head)) return true; list = list.tail; } return false; } }