/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.functions;
import java.io.Serializable;
import java.util.Iterator;
import xxl.core.predicates.PredicateFunctional.UnaryPredicate;
public class Functional {
private Functional(){}
public interface NullaryFunction<T> extends Serializable {
public T invoke();
}
public interface UnaryFunction<I, O> extends Serializable {
public O invoke(I arg);
}
public interface BinaryFunction<I0, I1, O> extends Serializable {
public O invoke(I0 arg0, I1 arg1);
}
public interface TrinaryFunction<I0, I1, I2, O> extends Serializable {
public O invoke(I0 arg0, I1 arg1, I2 arg2);
}
public static <I0,I1,O> UnaryFunction<I0,O> rightBind(final BinaryFunction<I0,I1,O> f, final I1 rightArg){
return new UnaryFunction<I0,O>(){
public O invoke(I0 leftArg) {
return f.invoke(leftArg, rightArg);
};
};
}
public static <I0,I1,O> UnaryFunction<I1,O> leftBind(final BinaryFunction<I0,I1,O> f, final I0 leftArg){
return new UnaryFunction<I1,O>(){
public O invoke(I1 rightArg) {
return f.invoke(leftArg, rightArg);
};
};
}
public static <I,T,O> UnaryFunction<I,O> compose(final UnaryFunction<I, T> f, final UnaryFunction<T,O> g){
return new UnaryFunction<I,O>(){
public O invoke(I arg) {
return g.invoke(f.invoke(arg));
};
};
}
public static class Identity<I> implements UnaryFunction<I, I>{
public I invoke(I arg) {
return arg;
};
}
public static class ArrayFactory<I1, I2, T> implements BinaryFunction<I1, Iterator<I2>, T[]>{
/**
* A factory method that gets one parameter and returns an array.
*/
protected UnaryFunction<I1, T[]> newArrayFactory;
/**
* A factory method that gets one parameter and returns an object used for
* initializing the array.
*/
protected UnaryFunction<I2, ? extends T> newObjectFactory;
/**
* Creates a new ArrayFactory.
*
* @param newArray factory method that returns an array.
* @param newObject factory method that returns the elements of the array.
*/
public ArrayFactory(UnaryFunction<I1, T[]> newArrayFactory, UnaryFunction<I2, ? extends T> newObjectFactory) {
this.newArrayFactory = newArrayFactory;
this.newObjectFactory = newObjectFactory;
}
/**
* Returns the result of the ArrayFactory as a typed array. This method
* calls the invoke method of the newArray function which returns an array
* of typed objects. After this, the invoke method of the newObject
* function is called, so many times as the length of the array. As
* parameter to the function an element of the iterator is given that is
* specified as second argument.
*
* @param must be an object used as argument to the newArrayFactory function.
* The second argument must be an iterator holding the arguments to
* the newObject function.
* @param must be an iterator holding the arguments to the newObjectFactory function.
* @return the initialized array.
*/
@Override
public T[] invoke(I1 arg0, Iterator<I2> arg1) {
T[] array = newArrayFactory.invoke(arg0);
for (int i = 0; i < array.length; i++)
array[i] = newObjectFactory.invoke(arg1.hasNext() ? arg1.next() : null);
return array;
}
}
public static class Iff<I0, I1, I2, O> implements TrinaryFunction<I0, I1, I2, O> {
/**
* providing the functionality of an if-clause.
*/
protected UnaryPredicate<? super I0> predicate;
/**
* using in the case of TRUE.
*/
protected UnaryFunction<? super I1, ? extends O> f1;
/**
* using in the case of FALSE.
*/
protected UnaryFunction<? super I2, ? extends O> f2;
public Iff(UnaryPredicate<? super I0> predicate, UnaryFunction<? super I1, ? extends O> f1, UnaryFunction<? super I2, ? extends O> f2){
this.predicate = predicate;
this.f1 = f1;
this.f2 = f2;
}
@Override
public O invoke(I0 arg0, I1 arg1, I2 arg2) {
return predicate.invoke(arg0) ?
f1.invoke(arg1) :
f2.invoke(arg2);
}
}
}