org.opencastproject.util.data.functions.Functions Maven / Gradle / Ivy
/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.util.data.functions;
import static org.opencastproject.util.data.Either.left;
import static org.opencastproject.util.data.Either.right;
import static org.opencastproject.util.data.Monadics.mlist;
import static org.opencastproject.util.data.Option.option;
import org.opencastproject.util.data.Effect;
import org.opencastproject.util.data.Effect0;
import org.opencastproject.util.data.Effect2;
import org.opencastproject.util.data.Either;
import org.opencastproject.util.data.Function;
import org.opencastproject.util.data.Function0;
import org.opencastproject.util.data.Function2;
import org.opencastproject.util.data.Option;
import org.opencastproject.util.data.Predicate;
import org.opencastproject.util.data.Tuple;
import com.entwinemedia.fn.Fn;
import java.util.List;
import java.util.Map;
/** General purpose functions, especially function transformations. */
public final class Functions {
private Functions() {
}
/** Create a function from the matterhorn-fn module from a common function. */
public static Fn fn(final Function f) {
return new Fn() {
@Override
public B apply(A a) {
return f.apply(a);
}
};
}
/** Function composition: f . g = f(g(x)) = o(f, g)
*/
public static Function o(final Function super B, ? extends C> f,
final Function super A, ? extends B> g) {
return new Function() {
@Override
public C apply(A a) {
return f.apply(g.apply(a));
}
};
}
/** Function composition: f . g = f(g) = o(f, g)
*/
public static Function0 o(final Function super A, ? extends B> f, final Function0 extends A> g) {
return new Function0() {
@Override
public B apply() {
return f.apply(g.apply());
}
};
}
/** f . g . h
*/
public static Function o(final Function super C, ? extends D> f,
final Function super B, ? extends C> g, final Function super A, ? extends B> h) {
return new Function() {
@Override
public D apply(A a) {
return f.apply(g.apply(h.apply(a)));
}
};
}
/** f . g . h . i
*/
public static Function o(final Function super D, ? extends E> f,
final Function super C, ? extends D> g, final Function super B, ? extends C> h,
final Function super A, ? extends B> i) {
return new Function() {
@Override
public E apply(A a) {
return f.apply(g.apply(h.apply(i.apply(a))));
}
};
}
/** Multiple `then` concatenation. f1 then f2 then ... fn */
public static Function concat(final Function super A, ? extends A>... fs) {
return new Function() {
@Override
public A apply(A a) {
A dc = a;
for (Function super A, ? extends A> f : fs) {
dc = f.apply(dc);
}
return dc;
}
};
}
/** Left to right composition: f then g = g(f(x))
*/
public static Function then(final Function super A, ? extends B> f,
final Function super B, ? extends C> g) {
return new Function() {
@Override
public C apply(A a) {
return g.apply(f.apply(a));
}
};
}
/** Left to right composition: f then g = g(f)
*/
public static Function0 then(final Function0 extends A> f, final Function super A, ? extends B> g) {
return new Function0() {
@Override
public B apply() {
return g.apply(f.apply());
}
};
}
/** Apply f
and ignore its result, then apply g
. */
public static Function0 then(final Function0 extends A> f, final Function0 extends B> g) {
return new Function0() {
@Override
public B apply() {
f.apply();
return g.apply();
}
};
}
/**
* Create a new function from f
decorated with an exception transformer. Any exception that occurs during
* application of f
is passed to transformer
whose return value is then being thrown.
*/
public static Function rethrow(final Function super A, ? extends B> f,
final Function super Exception, ? extends Exception> transformer) {
return new Function() {
@Override
public B apply(A a) {
try {
return f.apply(a);
} catch (Exception e) {
return chuck(transformer.apply(e));
}
}
};
}
/**
* Create a new function from f
decorated with an exception handler. Any exception that occurs during
* application of f
is passed to handler
whose return value is then being returned.
*/
public static Function handle(final Function super A, ? extends B> f,
final Function super Exception, ? extends B> handler) {
return new Function() {
@Override
public B apply(A a) {
try {
return f.apply(a);
} catch (Exception e) {
return handler.apply(e);
}
}
};
}
/**
* Create a new function from f
decorated with an exception handler. The new function either returns the
* value of f
or in case of an exception being thrown on the application of f
the return
* value of handler
.
*/
public static Function> either(final Function super A, ? extends B> f,
final Function super Exception, ? extends C> handler) {
return new Function>() {
@Override
public Either apply(A a) {
try {
B b = f.apply(a);
return right(b);
} catch (Exception e) {
C c = handler.apply(e);
return left(c);
}
}
};
}
/** Curry a function of arity 2. */
// todo rename since its actually partial application
public static Function curry(final Function2 super A, ? super B, ? extends C> f, final A a) {
return new Function() {
@Override
public C apply(B b) {
return f.apply(a, b);
}
};
}
/** Curry a function of arity 2. (a, b) -gt; c =gt; a -gt; b -gt; c */
public static Function> curry(final Function2 super A, ? super B, ? extends C> f) {
return new Function>() {
@Override
public Function apply(final A a) {
return new Function() {
@Override
public C apply(B b) {
return f.apply(a, b);
}
};
}
};
}
/** Uncurry to a function of arity 2. a -gt; b -gt; c =gt; (a, b) -gt; c */
public static Function2 uncurry(final Function super A, Function> f) {
return new Function2() {
@Override
public C apply(A a, B b) {
return f.apply(a).apply(b);
}
};
}
/** Curry a function of arity 1. */
public static Function0 curry(final Function super A, ? extends B> f, final A a) {
return new Function0() {
@Override
public B apply() {
return f.apply(a);
}
};
}
/** Curry a function of arity 1. */
public static Function> curry(final Function f) {
return new Function>() {
@Override
public Function0 apply(final A a) {
return new Function0() {
@Override
public B apply() {
return f.apply(a);
}
};
}
};
}
/** Create a tupled version of a function of arity 2. */
public static Function, C> tupled(final Function2 super A, ? super B, ? extends C> f) {
return new Function, C>() {
@Override
public C apply(Tuple t) {
return f.apply(t.getA(), t.getB());
}
};
}
/** Flip arguments of a function of arity 2. */
public static Function2 flip(final Function2 super A, ? super B, ? extends C> f) {
return new Function2() {
@Override
public C apply(B b, A a) {
return f.apply(a, b);
}
};
}
/** Turn a function of arity 0 into an effect by discarding its result. */
public static Effect0 toEffect(final Function0 f) {
return new Effect0() {
@Override
protected void run() {
f.apply();
}
};
}
/** Turn a function into an effect by discarding its result. */
public static Effect toEffect(final Function super A, ? extends B> f) {
return new Effect() {
@Override
protected void run(A a) {
f.apply(a);
}
};
}
/** Turn a function of arity 2 into an effect by discarding its result. */
public static Effect2 toEffect(final Function2 super A, ? super B, ? extends C> f) {
return new Effect2() {
@Override
protected void run(A a, B b) {
f.apply(a, b);
}
};
}
public static Predicate toPredicate(final Function super A, Boolean> f) {
return new Predicate() {
@Override
public Boolean apply(A a) {
return f.apply(a);
}
};
}
/** Noop effect. */
public static final Effect0 noop = new Effect0() {
@Override
protected void run() {
}
};
/** Noop effect. */
public static Effect noop() {
return new Effect() {
@Override
protected void run(A a) {
}
};
}
/** Identity function. */
public static Function identity() {
return new Function() {
@Override
public A apply(A a) {
return a;
}
};
}
/**
* Identity function. The type is based on the type of the example object to save some nasty typing, e.g.
* Function.<Integer>identity()
vs. identity(0)
*
* Please note that this constructor is only due to Java's insufficient type inference.
*/
public static Function identity(A example) {
return identity();
}
/**
* Identity function.
*
* @param clazz
* to describe the functions's type
*/
public static Function identity(Class clazz) {
return identity();
}
/** Constant function that always returns a
. */
public static Function0 constant0(final A a) {
return new Function0() {
@Override
public A apply() {
return a;
}
};
}
/** Constant function that always returns b
. */
public static Function constant(final B b) {
return new Function() {
@Override
public B apply(A ignore) {
return b;
}
};
}
/** Constant function that ignores its argument and always returns a
. */
public static Function ignore(final B b) {
return new Function() {
@Override
public B apply(A a) {
return b;
}
};
}
/** Promote function a -> b
to an {@link Option}. */
public static Function
© 2015 - 2025 Weber Informatics LLC | Privacy Policy