목차
1. 모나드
자, 함수형 프로그래밍의 기본 이론을 소개하는 것입니다. 더 알고 싶다면 실제로 Haskell이나 Lisp를 배우는 것이 좋습니다. 좀 더 정통적인 함수형 언어. 질문에 답해 봅시다: 실제 응용 프로그램에서 함수형 프로그래밍을 사용하는 것은 무엇입니까?
三、总结
웹 프론트엔드 JS 튜토리얼 JavaScript 함수형 프로그래밍 (3)

JavaScript 함수형 프로그래밍 (3)

Mar 06, 2017 pm 02:02 PM

두 번째 글에서는 Maybe, Either, IO, 어쩌면 등 몇 가지 일반적인 Functor를 소개했습니다. 두 번째 기사에는 의심이 생길 것입니다.

"이런 것들이 무슨 소용이 있습니까?" 』

사실 부작용이 적은 기능적 코드 작성을 배우고 싶다면 첫 번째 기사를 읽는 것으로 충분합니다. 두 번째 기사와 세 번째 기사는 몇 가지 기능적 이론 실습에 초점을 맞추고 있습니다. 예, 많은 휠이 이미 제작되어 구현하기가 매우 쉽기 때문에 실제 생산에 적용하기는 어렵습니다(그러나 불가능하지는 않습니다). 예를 들어, 현재 프런트 엔드에서 널리 사용되는 Promise의 비동기 호출 사양은 실제로 일종의 Monad입니다(나중에 논의할 예정). 점점 더 성숙해지는 Redux는 Flux의 변형으로 구현됩니다. , 핵심 개념도 상태 머신과 함수형 프로그래밍입니다.

1. 모나드

모나드에 대한 소개와 튜토리얼이 인터넷에 넘쳐나는데, 아래 글보다 더 좋은 글이 많아서 여기서는 간단하게 모나드를 소개하겠습니다. -물론, 이해하기 쉽다는 단점은 엄격하지 않다는 점 양해해주세요/w

Promise의 사양을 알고 계시다면 놀라운 기능을 기억하셔야 합니다. Promise:

doSomething()
    .then(result => {
        // 你可以return一个Promise链!
        return fetch('url').then(result => parseBody(result));
    })
    .then(result => {
        // 这里的result是上面那个Promise的终值
    })

doSomething()
    .then(result => {
        // 也可以直接return一个具体的值!
        return 123;
    })
    .then(result => {
        // result === 123
    })
로그인 후 복사


Promise의 콜백 함수의 경우 값을 직접 반환하거나 새 Promise를 반환할 수 있지만 후속 콜백 함수의 경우 둘 다 동일합니다. 이는 오랫동안 비판을 받아온 nodejs의 중첩 지옥을 깔끔하게 해결합니다.

사실 Promise는 일종의 모나드입니다. 예, 매일 많은 Promise를 작성해야 할 수도 있지만, 지금까지는 매일 사용하는 이것이 실제로 함수형이라는 사실을 몰랐습니다. 매우 높게 들리는 개념.

이제 실제로 모나드를 구현해 보겠습니다. 읽고 싶지 않다면 "Promise는 일종의 Monad입니다"만 기억하고 이 장을 건너뛰세요.

cat 함수를 작성해 보겠습니다. 이 함수의 기능은 Linux 명령줄의 cat과 동일합니다. 파일을 읽어서 내용을 인쇄합니다. 여기에서 IO 구현에 대해서는 이전 기사를 참조하세요:

import fs from 'fs';
import _ from 'lodash';

var map = _.curry((f, x) => x.map(f));
var compose = _.flowRight;

var readFile = function(filename) {
    return new IO(_ => fs.readFileSync(filename, 'utf-8'));
};

var print = function(x) {
    return new IO(_ => {
        console.log(x);
        return x;
    });
}

var cat = compose(map(print), readFile);

cat("file")
//=> IO(IO("file的内容"))
로그인 후 복사

여기에는 두 개의 IO가 관련되어 있으므로(파일 읽기 및 인쇄) 최종 결과는 두 개를 얻습니다. IO 레이어를 실행하려면

cat("file").__value().__value();
//=> 读取文件并打印到控制台
로그인 후 복사

만 호출하면 됩니다. 100개의 IO 작업이 필요하다면, 그렇게 해야 할까요? 100 __value( )를 쓰시겠습니까?

물론 우아하지 않을 수는 없습니다. 조인 메서드를 구현해 보겠습니다. 그 기능은 Functor의 레이어를 벗겨내고 내용을 우리에게 노출시키는 것입니다.

rree

조인 메서드를 사용한 후입니다. , 좀 더 우아하게:

var join = x => x.join();
IO.prototype.join = function() {
  return this.__value ? IO.of(null) : this.__value();
}

// 试试看
var foo = IO.of(IO.of('123'));

foo.join();
//=> IO('123')
로그인 후 복사


join 메소드는 Functor를 평면화할 수 있습니다(평탄화). , 우리는 일반적으로 이 기능을 갖춘 Functor를 Monad라고 부릅니다.

Functor 패키징 레이어를 아주 간단하게 제거하는 방법이 있지만, 우아한 프로그래머로서 map 🎜>join<🎜 후에 수동으로<를 항상 호출할 수는 없습니다. > 중복된 패키징을 제거합니다. 그렇지 않으면 코드는 다음과 같습니다:

var cat = compose(join, map(print), readFile);
cat("file").__value();
//=> 读取文件并打印到控制台
로그인 후 복사
그래서 우리가 기대하는 연결 호출을 달성하려면 chain이라는 메서드가 필요합니다. 이 메서드는 map 다음에 호출됩니다. 자동으로 Join을 호출하여 중복된 패키징을 제거합니다. 는 Monad의 주요 기능이기도 합니다.

var doSomething = compose(join, map(f), join, map(g), join, map(h));
로그인 후 복사


하하, 나오는 게 보이시죠?

체인

은 Promise의 then과 유사합니까? 예, 실제로 동작이 일관됩니다(그러면에는 좀 더 많은 논리가 있고 중첩 수준 수를 기록하고 Promise와 일반 반환 값을 구별합니다). Promise는 실제로 기능적인 Thought입니다. (원래는 Promise를 예로 들어 아래에 몇 가지 예시를 작성하고 싶었는데, 여기 보시는 분들은 다양한 Promise 체인을 능숙하게 작성할 수 있을 것 같아서 0w0은 쓰지 않겠습니다.)

간단히 말하면 Monad를 사용하면 중첩 지옥을 피하고 IO 및 기타 비동기 작업과 같이 깊게 중첩된 함수형 프로그래밍을 쉽게 수행할 수 있습니다.

2. 함수형 프로그래밍의 응용

자, 함수형 프로그래밍의 기본 이론을 소개하는 것입니다. 더 알고 싶다면 실제로 Haskell이나 Lisp를 배우는 것이 좋습니다. 좀 더 정통적인 함수형 언어. 질문에 답해 봅시다: 실제 응용 프로그램에서 함수형 프로그래밍을 사용하는 것은 무엇입니까?

1. 리액트

이제 리액트가 왜 인기가 있냐고 물으신다면 '성능이 좋다', '멋지다'라고 말씀하실 수도 있겠네요. ", " "풍부한 타사 구성 요소", "신규" 등이 있지만 이것이 가장 중요한 것은 아닙니다. 가장 중요한 것은 React가 기능 및 상태 기계라는 새로운 개념을 프런트 엔드 개발에 도입한다는 것입니다.

React에서 "순수 컴포넌트"를 작성하는 방법을 살펴보겠습니다.

var Text = props => (
    <p style={props.style}>{props.text}</p>
)
로그인 후 복사

咦这不就是纯函数吗?对于任意的 text 输入,都会产生唯一的固定输出,只不过这个输出是一个 virtual DOM 的元素罢了。配合状态机,就大大简化了前端开发的复杂度:

state => virtual DOM => 真实 DOM
로그인 후 복사

在 Redux 中更是可以把核心逻辑抽象成一个纯函数 reducer:

reducer(currentState, action) => newState
로그인 후 복사


关于 React+Redux(或者其它FLUX架构)就不在这里介绍太多了,有兴趣的可以参考相关的教程。

2、Rxjs

Rxjs 从诞生以来一直都不温不火,但它函数响应式编程(Functional Reactive Programming,FRP)的理念非常先进,虽然或许对于大部分应用环境来说,外部输入事件并不是太频繁,并不需要引入一个如此庞大的 FRP 体系,但我们也可以了解一下它有哪些优秀的特性。

在 Rxjs 中,所有的外部输入(用户输入、网络请求等等)都被视作一种 『事件流』:

--- 用户点击了按钮 --> 网络请求成功 --> 用户键盘输入 --> 某个定时事件发生 --> ......
로그인 후 복사

举个最简单的例子,下面这段代码会监听点击事件,每 2 次点击事件产生一次事件响应:

var clicks = Rx.Observable
    .fromEvent(document, &#39;click&#39;)
    .bufferCount(2)
    .subscribe(x => console.log(x)); // 打印出前2次点击事件
로그인 후 복사


其中 bufferCount 对于事件流的作用是这样的:

是不是很神奇呢?Rxjs 非常适合游戏、编辑器这种外部输入极多的应用,比如有的游戏可能有『搓大招』这个功能,即监听用户一系列连续的键盘、鼠标输入,比如上上下下左右左右BABA,不用事件流的思想的话,实现会非常困难且不优雅,但用 Rxjs 的话,就只是维护一个定长队列的问题而已:

var inputs = [];
var clicks = Rx.Observable
    .fromEvent(document, &#39;keydown&#39;)
    .scan((acc, cur) => {
        acc.push(cur.keyCode);
        var start = acc.length - 12 < 0 ? 0 : acc.length - 12;
        return acc.slice(start);
    }, inputs)
    .filter(x => x.join(&#39;,&#39;) == [38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 66, 65].join(&#39;,&#39;))// 上上下下左右左右BABA,这里用了比较奇技淫巧的数组对比方法
    .subscribe(x => console.log(&#39;!!!!!!ACE!!!!!!&#39;));
로그인 후 복사


当然,Rxjs 的作用远不止于此,但可以从这个范例里看出函数响应式编程的一些优良的特性。

3、Cycle.js

Cycle.js 是一个基于 Rxjs 的框架,它是一个彻彻底底的 FRP 理念的框架,和 React 一样支持 virtual DOM、JSX 语法,但现在似乎还没有看到大型的应用经验。

本质的讲,它就是在 Rxjs 的基础上加入了对 virtual DOM、容器和组件的支持,比如下面就是一个简单的『开关』按钮:

import xs from &#39;xstream&#39;;
import {run} from &#39;@cycle/xstream-run&#39;;
import {makeDOMDriver} from &#39;@cycle/dom&#39;;
import {html} from &#39;snabbdom-jsx&#39;;

function main(sources) {
  const sinks = {
    DOM: sources.DOM.select(&#39;input&#39;).events(&#39;click&#39;)
      .map(ev => ev.target.checked)
      .startWith(false)
      .map(toggled =>
        <p>
          <input type="checkbox" /> Toggle me
          <p>{toggled ? &#39;ON&#39; : &#39;off&#39;}</p>
        </p>
      )
  };
  return sinks;
}

const drivers = {
  DOM: makeDOMDriver(&#39;#app&#39;)
};

run(main, drivers);
로그인 후 복사


当然,Cycle.js 这种『侵入式』的框架适用性不是太广,因为使用它就意味着应用中必须全部或者大部分都要围绕它的理念设计,这对于大规模应用来说反而是负担。

三、总结

既然是完结篇,那我们来总结一下这三篇文章究竟讲了些啥?

第一篇文章里,介绍了纯函数、柯里化、Point Free、声明式代码和命令式代码的区别,你可能忘记得差不多了,但只要记住『函数对于外部状态的依赖是造成系统复杂性大大提高的主要原因』以及『让函数尽可能地纯净』就行了。

第二篇文章,或许是最没有也或许是最有干货的一篇,里面介绍了『容器』的概念和 MaybeEitherIO 这三个强大的 Functor。是的,大多数人或许都没有机会在生产环境中自己去实现这样的玩具级 Functor,但通过了解它们的特性会让你产生对于函数式编程的意识。

软件工程上讲『没有银弹』,函数式编程同样也不是万能的,它与烂大街的 OOP 一样,只是一种编程范式而已。很多实际应用中是很难用函数式去表达的,选择 OOP 亦或是其它编程范式或许会更简单。但我们要注意到函数式编程的核心理念,如果说 OOP 降低复杂度是靠良好的封装、继承、多态以及接口定义的话,那么函数式编程就是通过纯函数以及它们的组合、柯里化、Functor 等技术来降低系统复杂度,而 React、Rxjs、Cycle.js 正是这种理念的代言人,这可能是大势所趋,也或许是昙花一现,但不妨碍我们去多掌握一种编程范式嘛0w0

以上就是JavaScript函数式编程(三)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 Dec 17, 2023 pm 02:54 PM

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 Dec 17, 2023 pm 05:30 PM

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 Dec 17, 2023 am 09:39 AM

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 Dec 17, 2023 pm 12:09 PM

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 Jan 05, 2024 pm 06:08 PM

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

JavaScript와 WebSocket: 효율적인 실시간 일기예보 시스템 구축 JavaScript와 WebSocket: 효율적인 실시간 일기예보 시스템 구축 Dec 17, 2023 pm 05:13 PM

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 Jan 05, 2024 pm 01:37 PM

JavaScript에서 HTTP 상태 코드를 얻는 방법 소개: 프런트 엔드 개발에서 우리는 종종 백엔드 인터페이스와의 상호 작용을 처리해야 하며 HTTP 상태 코드는 매우 중요한 부분입니다. HTTP 상태 코드를 이해하고 얻는 것은 인터페이스에서 반환된 데이터를 더 잘 처리하는 데 도움이 됩니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. HTTP 상태 코드란 무엇입니까? HTTP 상태 코드는 브라우저가 서버에 요청을 시작할 때 서비스가

자바스크립트에서 insertBefore를 사용하는 방법 자바스크립트에서 insertBefore를 사용하는 방법 Nov 24, 2023 am 11:56 AM

사용법: JavaScript에서 insertBefore() 메서드는 DOM 트리에 새 노드를 삽입하는 데 사용됩니다. 이 방법에는 삽입할 새 노드와 참조 노드(즉, 새 노드가 삽입될 노드)라는 두 가지 매개 변수가 필요합니다.

See all articles