Java - create an existing static function

To make full use of the composition of functions in Java, I would like to archive some existing static functions that I usually use. An ideal candidate for curry is Apache Commons StringUtils .

For a specific example, let me say that I wanted to archive the StringUtils.remove(String str, String remove ) method to provide a function called (say) removeCommas .

One possible implementation:

 Function<String, String> removeCommas = s -> StringUtils.remove(s, ","); 

However, this is not curry. I would expect that I could use the method reference operator (e.g. StringUtils::remove ) to achieve this in a more functional way, but I can't figure out what the syntax will look like.

Thoughts?

+5
source share
3 answers

You can do remove() as follows:

 Function<String, Function<String, String>> remove = r -> s -> StringUtils.remove(s, r); Function<String, String> removeCommas = remove.apply(","); 

If you prefer a method reference, you can make a general 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 order of the parameters, so the above function will capture the target line before the delete line. There is no way to reorder the parameters in the method reference, so you will need to choose an order and stick to it.

+11
source

Plain Java does not provide syntactic sugar for currying. However, if you want to use a third-party library, you can use Javaslang .

In addition to arity 0..8 functions, it also contains proven functions (of the same arity) that allow you to throw exceptions. They provide the following functions:

  • partial application
  • exact functions
  • changed functions
  • memoized functions (= caching results)
  • functions with modified parameters
  • lift function
  • ...

In our specific case, here we need to turn over the list of parameters before learning (or partially applying) the removal 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 Function, Function2 extends Java BiFunction for compatibility.

Disclaimer: I am the creator of Javaslang

+2
source

Functional languages ​​have currying, because many functional languages ​​are limited to functions with only one parameter. This is inherited from lambda calculus, which is a formal language / system in the discipline of mathematical logic.

Currying overcomes this limitation, but simple Java does not support currying.


A few years ago I wrote a library called jcurry , here is an example . You may find this useful.

0
source

Source: https://habr.com/ru/post/1265522/


All Articles