To take full advantage of function composition in Java I'd like to curry some existing static functions that I commonly use. A perfect candidate for currying is Apache Commons StringUtils.
For a concrete example let's say I wanted to curry the StringUtils.remove(String str, String remove
) method to provide a function called (say) removeCommas
.
One possible implementation is:
Function<String, String> removeCommas = s -> StringUtils.remove(s, ",");
However this isn't currying. I would expect to be able to use method reference operator (eg StringUtils::remove
) to achieve this in a more functional way, but I cannot figure out what the syntax would look like.
Thoughts?
You can curry remove()
like this:
Function<String, Function<String, String>> remove = r -> s -> StringUtils.remove(s, r);
Function<String, String> removeCommas = remove.apply(",");
If you prefer the method reference, you can make a generic helper method to curry any fixed-arity method:
static <T, U, R> Function<T, Function<U, R>> curry(BiFunction<T, U, R> function) {
return a -> b -> function.apply(a, b);
}
// ...
Function<String, Function<String, String>> remove = curry(StringUtils::remove);
Note that this helper follows the parameter order, so the above function would capture the target string before the removal string. There's no way to reorder parameters in a method reference, so you would have to pick an order and stick with it.
Plain Java does not provide syntactic sugar for currying. However, if you are willing to use a third party library, you may use Javaslang.
Beside functions of arity 0..8, it also contains checked functions (of same arity) which allow to throw exceptions. These provide the following features:
In our concrete case here, we need the reversed parameter list before currying (or partially applying) the remove method:
// currying
final Function1<String, Function1<String, String>> curried =
Function2.of(StringUtils::remove).reversed().curried();
// partial application with reversed parameters
final Function1<String, String> removeCommas =
Function2.of(StringUtils::remove).reversed().apply(",");
Function1 extends Java's Function, Function2 extends Java's BiFunction for interoperability reasons.
Disclaimer: I'm the creator of Javaslang
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With