JS의 파이핑 또는 Elm이 부분적 적용에 대해 가르쳐준 것
16421 단어 functionaljavascriptelm
파이프 오퍼레이터란?
파이프 연산자는 한 함수의 출력을 다른 함수로 "파이프"합니다.
그래서 글을 쓰는 것보다
const result = c(b(a(x)));
또는 내가 선호하는 대로 다음과 같이 작성합니다.
const one = a(x);
const two = b(one);
const result = c(two);
다음과 같이 작성할 수 있습니다.
const result = a(x) |> b |> c;
JavaScript에는
.map()
, .filter()
및 .reduce()
와 같은 연결 방법과 유사한 것이 있습니다.그런 이유로 JS에서 파이핑을 탐색하고 Elm에서 배운 내용을 탐색하기 위한 스탠드로
.map()
를 사용할 것입니다.JS 및 Elm의 매핑
기본
.map()
예부터 시작하겠습니다.const square = (n) => n ** 2;
console.log([1, 2, 3].map(square));
// [1, 4, 9]
이것이 하는 일은 배열의 모든 항목에
square(n)
함수를 적용하고 해당 제곱 값이 포함된 새 배열을 반환하는 것입니다.이는 Elm에서 수행되는 방식과 유사합니다.
List.map square [1, 2, 3]
익명 화살표 기능을 사용하여 JS에서 위의 코드를 작성하는 또 다른 방법이 있습니다.
console.log([1, 2, 3].map(n => square(n)));
얼핏 보면 이 두 가지는 비슷해 보일 수 있지만 약간 다릅니다.
.map()
구문은 다음과 같습니다.Array.map(<function>)
첫 번째 방법은 배열의 모든 항목에
square(n)
함수를 적용하는 것입니다.두 번째 방법은
<function>
함수의 결과를 배열의 모든 항목에 반환하는 이 익명square(n)
을 적용하는 것입니다.첫 번째 구문은 기능적 언어에서 일반적입니다. 두 번째는 그렇지 않습니다. 다음 섹션에서 그 이유를 살펴보겠습니다.
부분 적용
부분 적용을 바로 시작하기 전에 이번에는 곱셈을 위한 또 다른 함수를 만들어 보겠습니다.
const multiply = (a, b) => a * b;
out
square(n)
함수와 달리 이 함수는 두 개의 매개변수를 사용합니다.배열에 10을 곱해 봅시다. 첫 번째 구문을 사용하면 다음과 같습니다.
console.log([1, 2, 3].map(multiply(10)));
// TypeError: NaN is not a function
답답하다!
multiply()
는 두 개의 인수를 사용하므로 첫 번째 구문을 사용할 수 없습니다.우리는 할 수 있습니다. 그러나 두 번째 스타일 구문을 사용하십시오.
console.log([1, 2, 3].map(n => multiply(10, n)));
// [ 10, 20, 30 ]
그리고 두 구문을 모두 사용하여 이 두 산술 함수를 함께 결합할 수도 있습니다.
console.log([1, 2, 3].map(square).map(n => multiply(10, n)));
// [ 10, 40, 90 ]
그러나 첫 번째 구문(Elm에서와 같이)을 사용하기를 원하거나 필요로 하는 경우. 그런 다음 부분 적용을 사용해야 합니다.
multiply()
함수를 리팩토링하여 부분 적용을 사용하도록 합시다.const multiplyPartial = (a) => (b) => a * b;
당신이 나와 같은 단순한 자바스크립트 개발자라면 아마도 당신의 두뇌를 손상시키고 당신을 약간 전율하게 만들었을 것입니다.
두 개의 매개변수 대신
multiplyPartial
는 두 개의 함수와 같습니다. 첫 번째 함수는 두 입력의 곱을 반환하는 다른 함수를 반환합니다.부분 적용으로 다음과 같은 함수를 작성할 수 있습니다.
const multiplyPartial10 = multiplyPartial(10);
multiplyPartial10
함수는 이제 b
인수를 사용할 수 있으며 두 인수의 곱을 반환합니다.multiplyPartial10(4)
// 40
우리가 얻은 오류로 돌아가서 부분 적용을 사용하여 다음을 수행할 수 있습니다.
console.log([1, 2, 3].map(multiplyPartial(10)));
// [10, 20, 30]
// or even
console.log([1, 2, 3].map(multiplyPartial10));
// [10, 20, 30]
다시 함수
multiplyPartial(10)
는 함수를 반환하고 해당 함수는 배열의 각 요소에 적용됩니다.혼합 유형
JavaScript에서 매개변수가 두 가지 유형인 함수는 완벽하게 괜찮습니다.
const mixedTypesOne = (a, b) => a.toUpperCase() + " " + (b * 10);
const mixedTypesTwo = (a, b) => b.toUpperCase() + " " + (a * 10);
둘 다 다음을 제공합니다.
console.log([1, 2, 3].map(n => mixedTypesOne("This number multiplied by 10 is", n)));
console.log([1, 2, 3].map(n => mixedTypesTwo(n, "This number multiplied by 10 is")));
// [
// 'THIS NUMBER MULTIPLIED BY 10 IS 10',
// 'THIS NUMBER MULTIPLIED BY 10 IS 20',
// 'THIS NUMBER MULTIPLIED BY 10 IS 30'
// ]
mixedTypes
함수에서 어떤 유형이 먼저 오는지에 관계없이 map()
의 화살표 구문을 사용하여 올바른 인수를 전달할 수 있습니다.이제 부분 적용을 사용하여 리팩터링해 보겠습니다.
const mixedTypesPartialOne = (a) => (b) => a.toUpperCase() + " " + (b * 10);
const mixedTypesPartialTwo = (a) => (b) => b.toUpperCase() + " " + (a * 10);
첫 번째를 실행하면 다음이 제공됩니다.
console.log([1, 2, 3].map(mixedTypesPartialOne("This number multiplied by 10 is")));
// [
// 'THIS NUMBER MULTIPLIED BY 10 IS 10',
// 'THIS NUMBER MULTIPLIED BY 10 IS 20',
// 'THIS NUMBER MULTIPLIED BY 10 IS 30'
// ]
그러나 두 번째:
console.log([1, 2, 3].map(mixedTypesPartialTwo("This number multiplied by 10 is")));
// TypeError: b.toUpperCase is not a function
mixedTypesPartialTwo
에서 b
로 전달된 인수는 문자열이 아니라 숫자입니다.그래서 뭐?
위의 예에서 알 수 있듯이 파이핑 및 부분 적용은 일부 일반적인 JavaScript 사례, 즉 두 개의 매개 변수가 있는 함수와 항상 잘 작동하지 않습니다.
Elm에서 함수는 하나의 인수1만 사용하고 부분 적용이 나머지를 수행합니다.
나는 파이프 연산자에 대해 신이 나지만 코드 작성 방법에 대해 조금 다르게 생각해야 한다는 것을 의미합니다. 나는 이 개념에 약간 어려움을 겪었으므로 이것이 다른 사람들을 도울 수 있기를 바랍니다.
So conceptually, every function accepts one argument. ↩
Reference
이 문제에 관하여(JS의 파이핑 또는 Elm이 부분적 적용에 대해 가르쳐준 것), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/charlesloder/piping-in-js-or-what-elm-taught-me-about-partial-application-494l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)