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.set과 f의 타입을 비교해 볼 수 있어요: 바인딩된 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은 밑줄_지원이 없어 인자를 왼쪽에서 오른쪽으로만 바인딩할 수 있었습니다. 밑줄을 택하는 선택은 논란이 많았고 여러 다른 제안이 있었지만 그 어느 것도 우월하다고 여겨지지 않았습니다. 결국 밑줄_은 적어도 "여기에 값 채우기"처럼 보여 그 의미를 잘 설명합니다.
본문
bind와 밑줄
함수.bind(인자...)로 부분 적용 함수를 만듭니다. _는 바인딩되지 않는 인자를 나타내요. 예: map.set.bind(_, "12")는 Int->Void 함수를 만들고 인덱스 1에 "12"를 설정합니다.
선택적 인자 처리
기본적으로 끝의 선택적 인자는 기본값에 바인딩됩니다. _을 쓰면 결과 함수의 필수 인자가 돼요.