JavaScriptでの関数の組み合わせとカリー化を詳しく解説(例付き)
この記事では、JavaScript 関数の組み合わせとカリー化について詳しく説明します (例を示します)。必要な方は参考にしていただければ幸いです。
私たちは皆、オブジェクト指向 SOLID における単一責任原則 (SRP、単一責任原則) を知っています。関数型プログラミングでは、各関数は 1 つの単位であり、実行することは 1 つだけです。しかし、現実の世界は常に複雑であり、現実の世界をプログラミングにマッピングする場合、単一の関数ではあまり意味がありません。このとき、関数の合成とカリー化が必要になります。
チェーン コール
jQuery を使用したことがある場合は、$('.post').eq(1).attr('data などのチェーン コールが何であるかをご存知でしょう。 - test', 'test')
.JavaScript のネイティブ文字列および配列メソッドの一部は、チェーン呼び出しスタイルを記述することもできます:
'Hello, world!'.split('').reverse().join('') // "!dlrow ,olleH"
まず第一に、チェーン呼び出しは上記のオブジェクトに基づいています。メソッド split
、reverse
、join
は、前のオブジェクト「Hello, world!」から分離されている場合は再生できません。
関数型プログラミングでは、メソッドはデータから独立しています。関数型の方法で上記を書くことができます。
const split = (tag, xs) => xs.split(tag) const reverse = xs => xs.reverse() const join = (tag, xs) => xs.join(tag) join('',reverse(split('','Hello, world!'))) // "!dlrow ,olleH"
あなたは間違いなく、冗談だと言うでしょう。これは連鎖呼び出しよりもどのように優れているのでしょうか?これは依然としてデータに依存しています。「Hello, world!」を渡さないと、一連の関数の組み合わせは機能しません。ここでの唯一の利点は、個々のメソッドを再利用できることです。パニックにならないでください。後でコンテンツがたくさんあるので、私が最適化します (愚かにも)。変換を進める前に、まず部分適用とカリー化という 2 つの概念を紹介します。
部分アプリケーション
部分アプリケーションは、いくつかのパラメータを受け取り、受け取ったパラメータの少ない関数を返すプロセスです。これはアプリケーションの一部です。 bind
を使用して実装します。
const addThreeArg = (x, y, z) => x + y + z; const addTwoArg = addThreeNumber.bind(null, 1) const addOneArg = addThreeNumber.bind(null, 1, 2) addTwoArg(2, 3) // 6 addOneArg(7) // 10
上記は bind
を使用して、残りのパラメーターをそれぞれ受け入れる他の 2 つの関数を生成します。これはアプリケーションの一部です。もちろん、他の方法でも行うことができます。
一部のアプリケーションの問題
一部のアプリケーションの主な問題は、返される関数の型を直接推論できないことです。前述したように、一部のアプリケーションは、返されるパラメーターの数を指定せずに、より少ないパラメーターを受け入れる関数を返します。これは暗黙的なものなので、コードを確認する必要があります。そうして初めて、返された関数が受け取るパラメーターの数がわかります。
カリー化
カリー化の定義: 関数を呼び出すことはできますが、すべてのパラメーターを一度に渡すことはできません。この関数は、次の 1 つの パラメータを受け取る関数を返します。
const add = x => y => x + y const plusOne = add(1) plusOne(10) // 11
カリー化された関数は、パラメーターを 1 つだけ受け取る関数を返し、返される関数の型は予測可能です。
もちろん、実際の開発では、多くの関数はカリー化されていません。いくつかのツール関数を使用して変換できます。
const curry = (fn) => { // fn可以是任何参数的函数 const arity = fn.length; return function $curry(...args) { if (args.length < arity) { return $curry.bind(null, ...args); } return fn.call(null, ...args); }; };
オープン ソース ライブラリ Ramda で提供されているカリー メソッドを使用することもできます。
ああ、カレーです。機能は何ですか?
例
const currySplit = curry((tag, xs) => xs.split(tag)) const split = (tag, xs) => xs.split(tag) // 我现在需要一个函数去split "," const splitComma = currySplit(',') //by curry const splitComma = string => split(',', string)
カリー関数が新しい関数を生成するとき、それはデータとは何の関係もないことがわかります。新しい関数を生成する 2 つのプロセスを比較すると、カリー化を行わないプロセスは比較的冗長です。
関数の組み合わせ
最初にコードを指定します:
const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0];
実際、compose は合計 2 つのことを行います:
Receives関数のセット、関数を返します。関数はすぐには実行されません。
結合関数。渡された関数を左から右に結合します。
一部の学生は上記のreduceRightにあまり慣れていないかもしれません。2元と3元の例を挙げましょう:
const compose = (f, g) => (...args) => f(g(...args)) const compose3 = (f, g, z) => (...args) => f(g(z(...args)))
関数呼び出しは左から順に行われます。右、データ 左から右への流れも同様です。もちろん、右から左へを定義することはできますが、意味的にはそれほど意味がありません。
さて、最初の例を最適化しましょう:
const split = curry((tag, xs) => xs.split(tag)) const reverse = xs => xs.reverse() const join = curry((tag, xs) => xs.join(tag)) const reverseWords = compose(join(''), reverse, split('')) reverseWords('Hello,world!');
これははるかにシンプルで理解しやすいでしょうか?ここの reverseWords
は、前に説明した Pointfree コード スタイルでもあります。データや外部状態に依存せず、組み合わせた関数です。
Pointfree 前回の記事で JS 関数型プログラミングの概念を紹介し、その利点と欠点についても説明しました。興味のある方はぜひご覧ください。
関数結合の結合法則
まず、小学校の知識の足し算の結合法則: a (b c)=(a b) c
を確認しましょう。説明はしませんが、理解できるはずです。
振り返ってみると、実際には関数の組み合わせには結合法則があります。
compose(f, compose(g, h)) === compose(compose(f, g), h);
これは、関数の組み合わせを自由に組み合わせてキャッシュできるという利点です。
const split = curry((tag, xs) => xs.split(tag)) const reverse = xs => xs.reverse() const join = curry((tag, xs) => xs.join(tag)) const getReverseArray = compose(reverse, split('')) const reverseWords = compose(join(''), getReverseArray) reverseWords('Hello,world!');
補足。心理図: ###########################
以上がJavaScriptでの関数の組み合わせとカリー化を詳しく解説(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

C++ ラムダ式は、関数型プログラミングに次のような利点をもたらします。 シンプルさ: 匿名インライン関数により、コードの可読性が向上します。コードの再利用: コードの再利用を容易にするために、ラムダ式を渡したり保存したりできます。カプセル化: 別の関数を作成せずにコードの一部をカプセル化する方法を提供します。実際のケース: リスト内の奇数をフィルタリングします。リスト内の要素の合計を計算します。ラムダ式は、関数型プログラミングの簡素化、再利用性、カプセル化を実現します。

Go では、遅延データ構造を使用して遅延評価を実装できます。実際の値をカプセル化し、必要な場合にのみ評価するラッパー型を作成します。関数型プログラムでのフィボナッチ数列の計算を最適化し、実際に必要になるまで中間値の計算を延期します。これにより、不要なオーバーヘッドが排除され、関数型プログラムのパフォーマンスが向上します。

Go で関数型プログラミングを使用する場合に注意すべき 5 つの一般的な間違いと落とし穴があります。 参照を誤って変更することを避け、新しく作成された変数が返されるようにしてください。同時実行の問題を解決するには、同期メカニズムを使用するか、外部の可変状態のキャプチャを避けます。コードの可読性と保守性を向上させるために、部分的な機能化は控えめに使用してください。アプリケーションの堅牢性を確保するために、常に関数内のエラーを処理してください。パフォーマンスへの影響を考慮し、インライン関数、フラット化されたデータ構造、操作のバッチ処理を使用してコードを最適化します。

JS-Torch の概要 JS-Torch は、構文が PyTorch に非常に似ている深層学習 JavaScript ライブラリです。これには、完全に機能するテンソル オブジェクト (追跡された勾配で使用可能)、深層学習レイヤーと関数、および自動微分エンジンが含まれています。 JS-Torch は JavaScript での深層学習の研究に適しており、深層学習の開発を加速するための便利なツールや機能を多数提供します。 Image PyTorch は、Meta の研究チームによって開発および保守されているオープンソースの深層学習フレームワークです。ニューラル ネットワーク モデルを構築およびトレーニングするための豊富なツールとライブラリのセットを提供します。 PyTorch は、シンプル、柔軟、そして使いやすいように設計されており、その動的な計算グラフ機能により、

Python のラムダ式は、匿名関数の別の構文形式です。これは、プログラム内のどこにでも定義できる小さな匿名関数です。ラムダ式はパラメータ リストと式で構成されます。式には有効な Python 式を使用できます。ラムダ式の構文は次のとおりです: lambdaargument_list:expression. たとえば、次のラムダ式は 2 つの数値の合計を返します: lambdax,y:x+y. このラムダ式は、マップなどの他の関数に渡すことができます。 () 関数:数値=[ 1,2,3,4,5]結果=マップ(ラムダ

pythonLambda 式は、簡潔で読みやすく、使いやすいコードを作成するための強力で柔軟なツールです。これらは、他の関数に引数として渡したり、変数に保存したりできる匿名関数をすばやく作成するのに最適です。 Lambda 式の基本構文は次のとおりです。 lambdaarguments:expression たとえば、次の Lambda 式は 2 つの数値を加算します: lambdax,y:x+y この Lambda 式は、次のように引数として別の関数に渡すことができます。 defsum( x ,y):returnx+yresult=sum(lambdax,y:x+y,1,2) この例では

Go と Node.js には、型指定 (強い/弱い)、同時実行性 (ゴルーチン/イベント ループ)、ガベージ コレクション (自動/手動) の違いがあります。 Go は高スループットと低レイテンシーを備えており、高負荷のバックエンドに適しています。Node.js は非同期 I/O に優れており、高い同時実行性と短いリクエストに適しています。この 2 つの実際のケースには、Kubernetes (Go)、データベース接続 (Node.js)、Web アプリケーション (Go/Node.js) が含まれます。最終的な選択は、アプリケーションのニーズ、チームのスキル、個人の好みによって異なります。
