001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2007 Robert Grimm, New York University
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public License
007: * version 2.1 as published by the Free Software Foundation.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.util;
020:
021: /**
022: * Function definitions.
023: *
024: * @author Laune Harris
025: * @author Robert Grimm
026: * @version $Revision: 1.5 $
027: */
028: public class Function {
029:
030: /** Hidden constructor. */
031: private Function() { /* Nothing to do. */
032: }
033:
034: /** A function with no arguments. */
035: public static interface F0<R> {
036: R apply();
037: }
038:
039: /** A function with one argument. */
040: public static interface F1<R, A> {
041: R apply(A a);
042: }
043:
044: /** A function with two arguments. */
045: public static interface F2<R, A, B> {
046: R apply(A a, B b);
047: }
048:
049: /** A function with three arguments. */
050: public static interface F3<R, A, B, C> {
051: R apply(A a, B b, C c);
052: }
053:
054: /** A function with four arguments. */
055: public static interface F4<R, A, B, C, D> {
056: R apply(A a, B b, C c, D d);
057: }
058:
059: /** A function with five arguments. */
060: public static interface F5<R, A, B, C, D, E> {
061: R apply(A a, B b, C c, D d, E e);
062: }
063:
064: /** A function with six arguments. */
065: public static interface F6<R, A, B, C, D, E, F> {
066: R apply(A a, B b, C c, D d, E e, F f);
067: }
068:
069: /** A function with seven arguments. */
070: public static interface F7<R, A, B, C, D, E, F, G> {
071: R apply(A a, B b, C c, D d, E e, F f, G g);
072: }
073:
074: /** A function with eight arguments. */
075: public static interface F8<R, A, B, C, D, E, F, G, H> {
076: R apply(A a, B b, C c, D d, E e, F f, G g, H h);
077: }
078:
079: /** A function with nine arguments. */
080: public static interface F9<R, A, B, C, D, E, F, G, H> {
081: R apply(A a, B b, C c, D d, E e, F f, G g, H h);
082: }
083:
084: /** A function with ten arguments. */
085: public static interface F10<R, A, B, C, D, E, F, G, H, I> {
086: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i);
087: }
088:
089: /** A function with eleven arguments. */
090: public static interface F11<R, A, B, C, D, E, F, G, H, I, J> {
091: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
092: }
093:
094: /** A function with twelve arguments. */
095: public static interface F12<R, A, B, C, D, E, F, G, H, I, J, K> {
096: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
097: }
098:
099: /** A function with thirteen arguments. */
100: public static interface F13<R, A, B, C, D, E, F, G, H, I, J, K, L> {
101: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k,
102: L l);
103: }
104:
105: /** A function with fourteen arguments. */
106: public static interface F14<R, A, B, C, D, E, F, G, H, I, J, K, L, M> {
107: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k,
108: L l, M m);
109: }
110:
111: /** A function with fifteen arguments. */
112: public static interface F15<R, A, B, C, D, E, F, G, H, I, J, K, L, M, N> {
113: R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k,
114: L l, M m, N n);
115: }
116:
117: /**
118: * Iterate the specified function over the specified list.
119: *
120: * @param function The function.
121: * @param list The list.
122: */
123: public static <T, U> void iterate(
124: Function.F1<U, ? super T> function, Pair<T> list) {
125: while (Pair.EMPTY != list) {
126: function.apply(list.head);
127: list = list.tail;
128: }
129: }
130:
131: /**
132: * Map the specified function over the specified list. Note that
133: * the implementation does not recurse.
134: *
135: * @param function The function.
136: * @param list The list.
137: * @return The result of mapping the function.
138: */
139: public static <T, U> Pair<U> map(
140: Function.F1<U, ? super T> function, Pair<T> list) {
141: if (Pair.EMPTY == list)
142: return Pair.empty();
143:
144: Pair<U> result = new Pair<U>(function.apply(list.head));
145: Pair<U> cursor = result;
146:
147: while (Pair.EMPTY != list.tail) {
148: list = list.tail;
149: cursor.tail = new Pair<U>(function.apply(list.head));
150: cursor = cursor.tail;
151: }
152:
153: return result;
154: }
155:
156: /**
157: * Fold the specified list with the specified function. This method
158: * successively applies the specified function to each of the list's
159: * elements and a running result, which is initialized to the
160: * specified seed.
161: *
162: * @param function The function.
163: * @param seed The seed value.
164: * @param list The list.
165: * @return The folded value.
166: */
167: public static <T, U> U foldl(Function.F2<U, ? super T, U> function,
168: U seed, Pair<T> list) {
169: while (Pair.EMPTY != list) {
170: seed = function.apply(list.head, seed);
171: list = list.tail;
172: }
173: return seed;
174: }
175:
176: /**
177: * Determine whether the specified list contains only elements
178: * matching the specified predicate.
179: *
180: * @param pred The predicate.
181: * @param list The list.
182: * @return <code>true</code> if the list contains only matching
183: * elements.
184: */
185: public static <T> boolean matchesAll(
186: Function.F1<Boolean, ? super T> pred, Pair<T> list) {
187: while (Pair.EMPTY != list) {
188: if (!pred.apply(list.head))
189: return false;
190: list = list.tail;
191: }
192: return true;
193: }
194:
195: /**
196: * Determine whether the specified list contains an element matching
197: * the specified predicate.
198: *
199: * @param pred The predicate.
200: * @param list The list.
201: * @return <code>true</code> if the list contains at least one
202: * matching element.
203: */
204: public static <T> boolean matchesOne(
205: Function.F1<Boolean, ? super T> pred, Pair<T> list) {
206: while (Pair.EMPTY != list) {
207: if (pred.apply(list.head))
208: return true;
209: list = list.tail;
210: }
211: return false;
212: }
213:
214: }
|