기능 프로그래머가 되길 원합니다 (3 부)

기능 프로그래밍 개념을 이해하기위한 첫 번째 단계를 취하는 것이 가장 중요하고 때로는 가장 어려운 단계입니다. 하지만 꼭 그럴 필요는 없습니다. 올바른 관점이 아닙니다.

이전 부품 : 1 부, 2 부

기능 구성

프로그래머로서 우리는 게으르다. 우리는 계속해서 반복해서 작성한 코드를 빌드, 테스트 및 배포하고 싶지 않습니다.

우리는 항상 일을 한 번 수행하는 방법과 다른 일을 위해 재사용 할 수있는 방법을 찾으려고 노력하고 있습니다.

코드 재사용은 훌륭하게 들리지만 달성하기는 어렵습니다. 코드를 너무 구체적으로 지정하면 재사용 할 수 없습니다. 그것을 너무 일반적으로 만들고 처음에는 사용하기가 너무 어려울 수 있습니다.

따라서 더 복잡한 기능을 구축하기 위해 빌딩 블록으로 사용할 수있는 더 작고 재사용 가능한 조각을 만드는 방법 인 두 가지 사이의 균형이 필요합니다.

함수형 프로그래밍에서 함수는 빌딩 블록입니다. 매우 구체적인 작업을 수행하기 위해 작성하고 레고 블록과 같이 구성합니다.

이것을 기능 구성이라고합니다.

어떻게 작동합니까? 두 가지 자바 스크립트 함수로 시작해 보겠습니다.

var add10 = 함수 (값) {
    반환 값 + 10;
};
var mult5 = 함수 (값) {
    반환 값 * 5;
};

이것은 너무 장황하므로 팻 화살표 표기법을 사용하여 다시 작성해 보겠습니다.

var add10 = 값 => 값 + 10;
var mult5 = 값 => 값 * 5;

그게 낫다. 이제 값을 가져 와서 10을 더한 다음 결과에 5를 곱하는 함수를 원한다고 가정 해 봅시다.

var mult5AfterAdd10 = 값 => 5 * (값 + 10)

매우 간단한 예이지만이 기능을 처음부터 작성하지 않아도됩니다. 첫째, 괄호를 잊어 버리는 것과 같은 실수를 할 수 있습니다.

둘째, 우리는 이미 10을 더하고 5를 곱하는 함수를 이미 가지고 있습니다. 우리는 이미 작성한 코드를 작성하고 있습니다.

대신 add10과 mult5를 사용하여 새로운 기능을 만들어 봅시다 :

var mult5AfterAdd10 = 값 => mult5 (add10 (값));

방금 기존 함수를 사용하여 mult5AfterAdd10을 만들었지 만 더 좋은 방법이 있습니다.

수학적으로, f ° g는 기능적 구성 요소이고 "f로 구성된 f"또는보다 일반적으로 "f after g"로 읽습니다. 따라서 (f ∘ g) (x)는 x로 x를 호출 한 후 또는 f (g (x))를 호출 한 후 f를 호출하는 것과 같습니다.

이 예에서는 mult5 ∘ add10 또는“mult5 after add10”이 있으므로 함수 이름 인 mult5AfterAdd10이 있습니다.

그것이 바로 우리가 한 일입니다. add10을 value 또는 간단히 mult5 (add10 (value))로 호출 한 후 mult5를 호출했습니다.

Javascript는 기본적으로 함수 구성을 수행하지 않으므로 Elm을 살펴 보겠습니다.

add10 값 =
    값 + 10
mult5 값 =
    값 * 5
mult5AfterAdd10 값 =
    (mult5 << add10) 값

<< 내장 연산자는 Elm에서 함수를 작성하는 방법입니다. 데이터가 어떻게 흐르는 지 시각적으로 보여줍니다. 먼저 값을 add10으로 전달한 다음 결과를 mult5로 전달합니다.

mult5AfterAdd10의 괄호, 즉 (mult5 << add10)에 유의하십시오. 그것들은 가치를 적용하기 전에 기능들이 먼저 구성되어 있는지 확인하기 위해 존재합니다.

이 방법으로 원하는만큼 많은 기능을 구성 할 수 있습니다.

f x =
   (g << h << s << r << t) x

여기서 x는 결과가 s로 전달되는 r로 결과가 전달되는 함수 t에 전달됩니다. 자바 스크립트에서 비슷한 것을하면 괄호 악몽 인 g (h (s (r (t (x)))))처럼 보일 것입니다

무점 표기법

Point-Free Notation이라는 매개 변수를 지정하지 않아도 쓰기 기능 스타일이 있습니다. 처음에는이 스타일이 이상하게 보이지만 계속 진행하면 간결한 점에 감사하게 될 것입니다.

mult5AfterAdd10에서 값이 두 번 지정되었음을 알 수 있습니다. 매개 변수 목록에 한 번 사용 된 경우 한 번

-1 개의 매개 변수를 기대하는 함수입니다
mult5AfterAdd10 값 =
    (mult5 << add10) 값

그러나 컴포지션에서 가장 오른쪽에있는 함수 인 add10이 동일한 매개 변수를 기대하므로이 매개 변수는 필요하지 않습니다. 다음 포인트 프리 버전은 동일합니다.

-이것은 또한 1 개의 매개 변수를 기대하는 함수입니다
mult5AfterAdd10 =
    (mult5 << add10)

포인트없는 버전을 사용하면 많은 이점이 있습니다.

먼저 중복 매개 변수를 지정할 필요가 없습니다. 또한 이름을 지정할 필요가 없으므로 모든 이름을 생각할 필요가 없습니다.

둘째, 덜 장황하기 때문에 읽고 이해하기가 더 쉽습니다. 이 예제는 간단하지만 더 많은 매개 변수를 사용하는 함수를 상상해보십시오.

낙원의 문제

지금까지 함수 구성의 작동 방식과 포인트 프리 표기법으로 기능을 지정하여 간결성, 명확성 및 유연성을 확보하는 방법을 살펴 보았습니다.

이제이 아이디어를 약간 다른 시나리오에서 사용하고 그 아이디어가 어떻게 작용하는지 살펴 보겠습니다. add10을 add로 대체한다고 상상해보십시오.

x y = 추가
    x + y
mult5 값 =
    값 * 5

이 두 함수만으로 mult5After10을 작성하는 방법은 무엇입니까?

계속 읽기 전에 조금만 생각해보십시오. 심각하지 않습니다. 생각 해봐 시도해보십시오.

좋아, 실제로 그것에 대해 생각하는 데 시간을 보낸다면 다음과 같은 해결책을 생각해 낼 수 있습니다.

-이건 잘못이야 !!!!
mult5AfterAdd10 =
    (mult5 << 추가) 10

그러나 이것은 작동하지 않습니다. 왜? add는 2 개의 매개 변수를 갖기 때문입니다.

Elm에서 이것이 분명하지 않으면 Javascript로 작성하십시오.

var mult5AfterAdd10 = mult5 (add (10)); // 작동하지 않습니다

이 코드는 틀리지 만 왜?

add 함수는 여기서 2 개의 매개 변수 중 하나만 가져 오므로 잘못된 결과는 mult5로 전달됩니다. 잘못된 결과가 생성됩니다.

실제로 Elm에서는 컴파일러가 잘못 작성된 코드 (Elm의 가장 큰 장점 중 하나)를 작성할 수 없습니다.

다시 해보자:

var mult5AfterAdd10 = y => mult5 (add (10, y)); // 포인트 프리

이것은 의미가 없지만 나는 이것과 함께 살 수있을 것입니다. 그러나 이제는 더 이상 기능을 결합하지 않습니다. 새로운 기능을 작성하고 있습니다. 또한 이것이 더 복잡해지면 예를 들어 mult5AfterAdd10을 다른 것으로 작성하고 싶다면 정말 문제가 생길 것입니다.

따라서 함수 구성은이 두 함수와 결혼 할 수 없기 때문에 유용성이 제한적인 것으로 보입니다. 너무 강력해서 너무 나빠요.

이 문제를 어떻게 해결할 수 있습니까? 이 문제를 해결하려면 무엇이 필요합니까?

글쎄, 정말 좋은 점은 add 함수에 매개 변수 중 하나만 미리 제공하고 나중에 mult5AfterAdd10이 호출 될 때 두 번째 매개 변수를 얻는 방법이 있다면 좋을 것입니다.

방법이 있고 Currying이라고합니다.

나의 두뇌!!!!

지금은 충분합니다.

이 기사의 다음 부분에서는 카레, 공통 기능 함수 (예 :지도, 필터, 접기 등), 참조 투명도 등에 대해 설명합니다.

다음 : 파트 4

이것을 좋아한다면 아래의 을 클릭하면 다른 사람들이 이것을 Medium에서 볼 수 있습니다.

Elm에서 Functional Programming을 사용하여 서로 배우고 웹 앱을 개발하도록 돕는 웹 개발자 커뮤니티에 참여하려면 내 Facebook 그룹을 확인하십시오. Elm Programming 알아보기 https://www.facebook.com/groups/learnelm/

내 트위터 : @cscalfani