5분 안에 설명: 일반 JavaScript의 모나드
위압적인 표지 사진에도 불구하고 가능한 한 어려운 수학을 사용하지 않고 모나드를 설명하려고 합니다. 범주 이론, Kleisli, 심지어 Curry에 대한 언급도 없습니다. NaN. _
위대한 더글라스 크록포드의 말:
훌륭하고 유용할 뿐만 아니라 저주를 받았고 모나드의 저주는 일단 깨달음을 얻으면 "아, 그게 뭔데"라고 이해하면 다른 사람에게 설명할 수 있는 능력을 잃게 된다는 것입니다.
글쎄요, 저는 이론이 있습니다. 모나드 이면의 수학적 이론과 어떻게 구현되어야 하는지에 대한 훌륭한 설명을 제공하는 이 주제에 대한 모든 훌륭한 기사 중에서 한 가지가 잘못되어 있기 때문입니다.
실제로 필요한 것은 무엇입니까?
알아보기 전에 한 가지 언급할 사항이 있습니다. 얼마 전에 나는 모나드 이면의 수학과 범주 이론에서의 위치에 대한 설명에 확고한 기반을 두지 않은 것을 기반으로 모나드를 이해하려고 시도해서는 안 된다는 것을 읽었습니다. 관심 있는 분들을 위해: 이 주제를 다루는 몇 가지 훌륭한 기사 가 있습니다 . 여기에서 반복하고 싶지 않기 때문에 지금 읽고(또는 최소한 스캔하고) 나중에 여기로 다시 오십시오(다음에 무슨 일이 일어나는지 이해하는 것이 전적으로 필요하지는 않다고 생각하지만).
자, 이제 문제를 해결했습니다. 모나드가 무엇인가요? 글쎄요, 그것을 표현하는 가장 간단한 방법은 — 어떤 값을 감싸는 것입니다. 함수형 프로그래밍 측면에서 모나드는 함수 를 적용할 수 있는 구조 인 functor 입니다. 값과 값을 입력하려는 모든 처리 사이의 추가 추상화 계층입니다. 그러나 그것은 우리에게 아무것도 말해주지 않습니다.
여러분이 상상할 수 있는 가장 단순한 모나드인 모나드 구현을 살펴보겠습니다 Identity.
const Identity = (value) => ({
value: () => value,
map: (fn) => Identity(fn(value)),
});
가능한 가장 간단한 예를 살펴보겠습니다.
const addTax = (value) => value * 1.1;
const cartValue = Identity(100);
const cartValueWithTax = cartValue
.map(addTax) // At this point this is Identity(110)
.value(); // Equal to 110 as a number
Identity모나드는 많은 함수형 프로그래밍 라이브러리의 함수 와 마찬가지로identity 꽤 투명한 논리를 가지고 있습니다. 자리 표시자 함수 와 같은 자리 표시자 모나드 입니다. 우리의 가치에 적용 하는 것은 위에 주어진 시나리오에서 잘 작동하지만 장바구니의 가치가 와 같다면 어떤 일이 일어날지 생각해 봅시다 . JavaScript가 작동하는 놀라운 방식 덕분에 우리는 .identityaddTaxundefinedNaN
일반적으로 이 문제를 해결하기 위한 가장 직관적인 방법은 addTax함수에 값에 대한 검사를 추가하는 것입니다. 이것은 잘못된 접근 방식입니다. 그것은 함수의 목적을 모호하게 하고 덜 순수하게 만듭니다. 함수 는 addTax단 한 가지, 단 한 가지만 수행해야 add합니다 Tax.
좋아요, 현명하신 분 - 당신은 말할 수 있습니다 - 우리가 그 undefined가치를 어떻게 고려해야 할까요? 글쎄, 그것이 우리가 모나드를 가지고 있는 이유입니다. 우리는 함수 를 순수하게 유지하고 싶습니다. 또한 함수에 전달하는 값에 따라 로직이 다르게 동작하기를 원합니다. 그 행동을 정의하는 가장 좋은 곳은 functor 입니다!
아마도 가장 인기 있는 모나드를 살펴보겠습니다: Maybe. of이것은 기본 구현일 수 있습니다( 명확성을 위해 모나드에서 접할 수 있는 일반적인 메서드는 그대로 둡니다 ).
const Maybe = (value) => ({
value: () => value,
map: (fn) => value === undefined || value === null
? Maybe(null)
: Maybe(fn(value)),
});
const primitiveCart = 100;
const undefinedCart = undefined;
const nullishCart = null;
const maybeCart = Maybe(100);
const maybeUndefinedCart = Maybe(undefined);
const maybeNullishCart = Maybe(null);
addTax(primitiveCart); // boring, 110
addTax(undefinedCart); // NaN
addTax(nullishCart); // 0 - thanks, JavaScript!
maybeCart.map(addTax).value(); // 110
maybeUndefinedCart.map(addTax).value(); // null
maybeNullishCart.map(addTax).value(); // null
물론 이것은 모나드를 사용하여 얻을 수 있는 엄청난 가능성의 극히 일부에 불과합니다. 호텔에 들어오는 모든 손님을 맞이하고 싶다고 가정해 보겠습니다.
const greet = (name) => `Hello, ${name}!`;
기본 예제를 하나만 더 살펴보겠습니다. 바로 Optional모나드입니다.
const Optional = (value) => ({
value: () => value,
orElse: (alternativeValue) => value
? Optional(value)
: Optional(alternativeValue),
map: (fn) => Optional(fn(value)),
});
const firstGuest = "John";
const anonymousGuest = undefined;
greet(firstGuest); // "Hello, John!"
greet(anonymousGuest); // "Hello, undefined" - this is a bit embarrasing
const OptionalWithStrangerFallback = (name) => Optional(name)
.orElse("stranger");
const firstGuestOptional = OptionalWithStrangerFallback(firstGuest);
const anonymousGuestOptional = OptionalWithStrangerFallback(anonymousGuest);
// I really hope you know where this is going at this point
firstGuestOptional.map(greet).value(); "Hello, John!"
anonymousGuestOptional.map(greet).value(); "Hello, stranger!"
이것이 모나드로 문제를 해결하기를 정말로 바랍니다. 아니라면 댓글로 알려주세요! 또한 JavaScript, 함수형 프로그래밍, 컴퓨터 비전, 아키텍처, 기하학, 밈, 기술 리더십 또는 위의 조합에 대한 더 많은 기사를 읽고 싶다면 여기 또는 LinkedIn 에서 저를 팔로우하세요 !

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































