6.9 함수 바인딩(Function Bindings)

6.9 함수 바인딩(Function Bindings)

Haxe 3은 부분 적용 인자로 함수를 바인딩하는 것을 허용합니다. 각 함수 타입은 bind 필드를 가진다고 간주될 수 있으며, 이것을 원하는 수의 인자로 호출해 새 함수를 만들 수 있습니다. 다음이 데모합니다:

class Main {
  static public function main() {
    var map = new haxe.ds.IntMap<String>();
    var f = map.set.bind(_, "12");
    $type(map.set); // Int -> String -> Void
    $type(f); // Int -> Void
    f(1);
    f(2);
    f(3);
    trace(map); // {1 => 12, 2 => 12, 3 => 12}
  }
}

4번째 줄은 map.set 함수를 변수 f에 바인딩하고 두 번째 인자로 12를 적용합니다. 밑줄 _은 이 인자가 바인딩되지 않았음을 나타내는 데 사용되며, 이는 map.setf의 타입을 비교해 볼 수 있어요: 바인딩된 String 인자는 타입에서 효과적으로 잘려 Int->String->Void 타입을 Int->Void로 바꿉니다.

f(1) 호출은 실제로 map.set(1, "12")를 호출하고, f(2)f(3) 호출도 유사합니다. 마지막 줄은 세 인덱스 모두 값 "12"에 매핑된다는 것을 증명합니다.

밑줄 _은 끝 인자(trailing arguments)에 대해 생략할 수 있어, map.set.bind(1)으로 첫 인자를 바인딩해 String->Void 함수(인덱스 1에 호출 시 새 값을 설정하는)를 만들 수 있습니다.

선택적 인자(Optional arguments)

기본적으로 끝의 선택적 인자들은 자신의 기본값에 바인딩되고 결과 함수의 인자가 되지 않아요. 이는 명시적 밑줄 _을 대신 사용해 변경할 수 있으며, 그 경우 원래 함수의 선택적 인자가 결과 함수의 필수 인자가 됩니다.

class Main {
  static function test(a:Int, ?b:String):Void {}

  static public function main() {
    var fn = test.bind(1);
    $type(fn); // Void->Void
    fn('foo'); // Compiler error: Too many arguments

    var fn = test.bind(1, _);
    $type(fn); // ?String->Void
    fn('foo'); // works
  }
}

추가 정보: Callback — Haxe 3 이전에 Haxe는 callback 키워드를 알고 있었는데, 함수 인자 뒤에 임의의 수의 바인딩 인자로 호출할 수 있었습니다. 그 이름은 this-객체가 바인딩된 콜백 함수를 만드는 일반적인 사용에서 비롯되었어요. Callback은 밑줄 _ 지원이 없어 인자를 왼쪽에서 오른쪽으로만 바인딩할 수 있었습니다. 밑줄을 택하는 선택은 논란이 많았고 여러 다른 제안이 있었지만 그 어느 것도 우월하다고 여겨지지 않았습니다. 결국 밑줄 _은 적어도 "여기에 값 채우기"처럼 보여 그 의미를 잘 설명합니다.

출처: Function Bindings

본문

bind와 밑줄

함수.bind(인자...)로 부분 적용 함수를 만듭니다. _는 바인딩되지 않는 인자를 나타내요. 예: map.set.bind(_, "12")Int->Void 함수를 만들고 인덱스 1에 "12"를 설정합니다.

선택적 인자 처리

기본적으로 끝의 선택적 인자는 기본값에 바인딩됩니다. _을 쓰면 결과 함수의 필수 인자가 돼요.

더 알아보기