import java.util.function.*;

interface Currying {
  public static <T, U, R> Function<U, R> leftSection(BiFunction<T, U, R> f, T left) {
    return right -> f.apply(left, right);
  }

  public static <T, U, R> Function<T, R> rightSection(BiFunction<T, U, R> f, U right) {
    return left -> f.apply( left, right );
  }

	// public static ... flip(...) { ... }

	// public static ... toUnary(...) { ... }

  public static void main(String[] args) {
    BinaryOperator<Number> minus = ( x, y ) -> x.doubleValue() - y.doubleValue();
    System.out.println( leftSection( minus, 4 ).apply( 3 ) );
    System.out.println( rightSection( minus, 4 ).apply( 3 ) );

    // ... concat = ...
    System.out.println(
      leftSection( flip( concat ), "5" ).apply("10").equals(
        rightSection( concat, "5" ).apply( "10" ) ) );

    System.out.println(
      rightSection( minus, 4 ).apply( 3 ).equals(
        toUnary( flip( minus ) ).apply( 4 ).apply( 3 ) ) );
  }
}

flip, toUnary, concat을 정의하세요.

  • toUnary( minus )하지 않고 lambda expression으로 currying function(partial function application)을 표현할 수 있습니다.
Function<Double, UnaryOperator<Double>> minus = x -> y -> x - y;
System.out.println( minus.apply( 3.0 ).apply( 5.0 ) ); // 3+5를 찍으세요.
  • 하지만 새로운 함수를 매번 만들어 쓰지 않고 작지만 되쓰임새가 또렷한 함수를 조립해서 쓰는 버릇을 기르는 게 함수로 프로그램 짜는 방식(functional programming style)을 익히는 데 도움이 됩니다.
  • leftSection, rightSection은 Haskell 언어의 간편 표기법을 흉내 낸 함수입니다.
  • functional inteface, java.lang.function의 쓰임새를 알고 generics (parametric polymorphism)와 type inference의 기본을 아울러 익히는 데 도움이 될까 싶어 만들어 본 문제입니다.
  • 한계점도 정확히 알고 있는 것이 시간과 노력을 아끼는 방법입니다. 문제도 풀어보세요.
마지막으로 고친 날