package org.fungsi.function;
import org.fungsi.Either;
import org.fungsi.Throwables;
import org.fungsi.Unit;
import java.util.function.Function;
@FunctionalInterface
public interface UnsafeFunction<T, R> {
R apply(T o) throws Throwable;
default Either<R, Throwable> safeApply(T o) {
try {
return Either.success(apply(o));
} catch (Throwable cause) {
return Either.failure(cause);
}
}
default Function<T, Either<R, Throwable>> safeFunction() {
return this::safeApply;
}
default Function<T, R> unsafeFunction() {
return o -> {
try {
return apply(o);
} catch (Throwable t) {
throw Throwables.propagate(t);
}
};
}
default UnsafeFunction<T, Either<R, Throwable>> eitherFunction() {
return this::safeApply;
}
default <TT> UnsafeFunction<TT, R> compose(UnsafeFunction<TT, T> other) {
return o -> this.apply(other.apply(o));
}
default <RR> UnsafeFunction<T, RR> andThen(UnsafeFunction<R, RR> other) {
return o -> other.apply(this.apply(o));
}
static final UnsafeFunction<Object, Object> IDENTITY = o -> o;
static final UnsafeFunction<Object, Object> NEVER = o -> { throw new IllegalStateException(); };
static final UnsafeFunction<Object, Unit> UNIT = o -> Unit.instance();
@SuppressWarnings("unchecked")
public static <T> UnsafeFunction<T, T> identity() {
return (UnsafeFunction<T, T>) IDENTITY;
}
@SuppressWarnings("unchecked")
public static <T, R> UnsafeFunction<T, R> never() {
return (UnsafeFunction<T, R>) NEVER;
}
@SuppressWarnings("unchecked")
public static <T> UnsafeFunction<T, Unit> unit() {
return (UnsafeFunction<T, Unit>) UNIT;
}
}