.curried & .uncurried
확장 게터로 제공하는 완전한 타입의 커링 — FxTS curry를 대신하는 Dart다운 방식입니다.
강의
커링은 인자가 여러 개인 함수를 단항 함수의 연쇄로 바꿉니다.
add(1, 2)가 add.curried(1)(2)가 되는 식입니다.
이렇게 얻는 것이 부분 적용입니다 — 첫 인자를 고정하면
새 함수가 나오고, 이는 map이나 filter 같은
함수가 원하는 콜백 형태와 정확히 일치합니다.
FxTS는 이를 curry(f)라는 함수로 제공하는데, 여기에는 Dart에
없는 두 가지가 쓰입니다. 런타임 항수 리플렉션(fn.length)과
재귀적 조건부 타입입니다. 그래서 FxDart는 항수(2–5)마다 확장을 하나씩
선언하고 모두 동일한 curried 게터를 노출한 뒤, 함수의
정적 타입을 보고 컴파일러가 알맞은 것을 고르게 합니다.
FxTS가 런타임에 하던 항수 분기가 컴파일 타임에 일어나는 셈이며,
그 결과는 캐스트 하나 없이 완전한 타입을 유지합니다.
add.curried(1)은 그 자체로 진짜
int Function(int)입니다.
.uncurried는 그 역입니다. 단항 함수의 연쇄를 다시 하나의
다인자 함수로 펼칩니다. 연쇄가 두 단계보다 깊게 중첩된 경우에는 가장
깊게 일치하는 항수가 선택되므로, 더 적은 단계만 펼치려면 확장을 명시적으로
적용하면 됩니다(Uncurry2(f).uncurried). 게터 이름이 왜
curry가 아니라 curried인지를 포함한 설계 전반의
이야기는
WHY_CURRIED.md에 있습니다.
데모 1 · 기본
데모 2 · 파이프라인에서의 부분 적용
커링된 이항 함수는 래퍼 클로저 없이 map에 그대로
들어갑니다:
데모 3 · uncurried로 왕복하기
직접 작성한 커링 클로저도 data-first 형태로 되돌릴 수 있으며,
curried와 uncurried는 정확한 역함수 관계입니다:
직접 해 보기
연습: 아래 clamp에 .curried를 써서
clampTo100 함수를 만들고, 리스트에 map으로 적용해 보세요.
add(1, 2)(3)에 해당하는 것은 없습니다. 명명된 매개변수와
타입이 그냥 Function인 값은 확장에 매칭되지 않으니 그런
곳에는 클로저를 쓰세요. 선택적 위치 매개변수는 매칭되지만,
연쇄 안에서는 그 자리가 필수가 됩니다. deprecated된 최상위
curry 스텁은 FxTS 마이그레이션을 이쪽으로 안내하기
위해서만 남아 있습니다.