Ну, Scala , Clojure или Haskell (или любой другой функциональный язык программирования ...), безусловно, языки , используемые для каррирования и других функциональных приемов.
Сказав это, безусловно, можно карри с Java без большого количества шаблонов, которые можно было бы ожидать (ну, хотя необходимость быть откровенным в отношении типов очень ранит - просто взгляните на пример curried
;-)),
Тесты, представленные ниже, демонстрируют как карри a Function3
в Function1 => Function1 => Function1
:
@Test
public void shouldCurryFunction() throws Exception {
// given
Function3<Integer, Integer, Integer, Integer> func = (a, b, c) -> a + b + c;
// when
Function<Integer, Function<Integer, Function<Integer, Integer>>> cur = curried(func);
// then
Function<Integer, Function<Integer, Integer>> step1 = cur.apply(1);
Function<Integer, Integer> step2 = step1.apply(2);
Integer result = step2.apply(3);
assertThat(result).isEqualTo(6);
}
, так и частичное применение , хотяв данном примере это не совсем безопасно:
@Test
public void shouldCurryOneArgument() throws Exception {
// given
Function3<Integer, Integer, Integer, Integer> adding = (a, b, c) -> a + b + c;
// when
Function2<Integer, Integer, Integer> curried = applyPartial(adding, _, _, put(1));
// then
Integer got = curried.apply(0, 0);
assertThat(got).isEqualTo(1);
}
Это взято из Proof of Concept, который я только что реализовал для развлечения перед JavaOne завтра через час, "потому что мне скучно" ;-) Коддоступно здесь: https://github.com/ktoso/jcurry
Общая идея может быть расширена до функции FunctionN => FunctionM, относительно легко, хотя «реальная безопасность типов» остается проблемой для примера приложения Partia, а для примера каррирования потребуетсячертовски много пародийного кода в jcurry , но это выполнимо.
В общем, это выполнимо, но в Scala это из коробки; -)