ホームページ ウェブフロントエンド jsチュートリアル 絶妙な自動カリー化機能をJSで実装する方法

絶妙な自動カリー化機能をJSで実装する方法

Dec 13, 2017 am 09:27 AM
javascript 関数 自動

この記事では、JS での絶妙な自動カリー化方法を詳細に分析し、コード例を通じてそのプロセスと原理を分析します。ぜひ参考にして勉強してください。

カレーとは何ですか?

コンピューターサイエンスにおいて、カリー化とは、複数のパラメーターを受け入れる関数を、単一のパラメーター (元の関数の最初のパラメーター) を受け入れる関数に変換し、残りのパラメーターを受け入れて結果を返す関数を返すことです。機能技術。この手法は、モーゼス シュンフィンケルとゴットロブ フレーゲによって発明されましたが、論理学者のハスケル カリーにちなんでクリストファー ストラチーによって命名されました。

理論は圧倒的だと思われますか?それは問題ではありません。最初にコードを見てみましょう:

Curriization application

リスト内の各要素に 1 つを追加するなど、リスト要素に対して何らかの処理を実行する関数を実装する必要があるとします。考えるのは簡単です:

const list = [0, 1, 2, 3];
list.map(elem => elem + 1);
ログイン後にコピー

それは簡単ですよね?さらに 2 つ追加したい場合はどうすればよいでしょうか?

const list = [0, 1, 2, 3];
list.map(elem => elem + 1);
list.map(elem => elem + 2);
ログイン後にコピー

処理関数をカプセル化できませんか?

しかし、map のコールバック関数は現在の要素 elem をパラメータとして受け入れるだけで、それをカプセル化する方法がないようです...

次のように思うかもしれません。部分的に設定された関数を取得できればいいのにと思います。例:

// plus返回部分配置好的函数
const plus1 = plus(1);
const plus2 = plus(2);
plus1(5); // => 6
plus2(7); // => 9
ログイン後にコピー

次のような関数をマップに渡します:

const list = [0, 1, 2, 3];
list.map(plus1); // => [1, 2, 3, 4]
list.map(plus2); // => [2, 3, 4, 5]
ログイン後にコピー

素晴らしいですね?この方法では、どれだけ追加しても、必要なのは list.map(plus(x)) だけです。これにより、カプセル化が完全に実装され、可読性が大幅に向上します。

しかし、ここで疑問が生じます: このようなプラス関数を実装するにはどうすればよいでしょうか?

ここでカリー化が便利です:

カリー化関数

// 原始的加法函数
function origPlus(a, b) {
 return a + b;
}
// 柯里化后的plus函数
function plus(a) {
 return function(b) {
  return a + b;
 }
}
// ES6写法
const plus = a => b => a + b;
ログイン後にコピー

ご覧のとおり、カリー化プラス関数は最初にパラメーター a を受け入れ、次にクロージャーによりパラメーター b 関数を返します。 function は親関数のパラメーター a にアクセスできるため、たとえば、 const plus2 = plus(2) は function plus2(b) { return 2 + b } と同等になり、部分的な構成が実現されます。

平たく言えば、カリー化は複数パラメーター関数を部分的に構成するプロセスであり、各ステップで単一パラメーターを受け入れる部分的に構成された関数が返されます。極端な場合には、複数の追加など、関数を部分的に何度も設定する必要がある場合があります。

multiPlus(1)(2)(3); // => 6
ログイン後にコピー

この書き方は奇妙に見えますよね。しかし、JS での関数型プログラミングの大きな落とし穴に陥ると、これが標準になります。


JS での自動カリー化の絶妙な実装

カリー化は関数型プログラミングの非常に重要な部分です (例: Haskell) は、デフォルトで関数を自動的にカリー化します。ただし、JS ではこれが行われないため、自動カリー化機能を自分で実装する必要があります。

まずコードを入力してください:

// ES5
function curry(fn) {
 function _c(restNum, argsList) {
  return restNum === 0 ?
   fn.apply(null, argsList) :
   function(x) {
    return _c(restNum - 1, argsList.concat(x));
   };
 }
 return _c(fn.length, []);
}
// ES6
const curry = fn => {
 const _c = (restNum, argsList) => restNum === 0 ?
  fn(...argsList) : x => _c(restNum - 1, [...argsList, x]);
 return _c(fn.length, []);
}
/***************** 使用 *********************/
var plus = curry(function(a, b) {
 return a + b;
});
// ES6
const plus = curry((a, b) => a + b);
plus(2)(4); // => 6
ログイン後にコピー

このようにして自動カリー化が実現します。

何が起こったのか理解できたなら、おめでとうございます!みんながあなたを呼ぶボスはあなたです! 、「いいね!」を残して、職務上のキャリアを開始してください (面白い

何が起こっているのか理解できなくても、心配しないでください。今すぐアイデアを整理するお手伝いをします。

要件分析

カレーが必要ですカリー化する関数をパラメータとして受け取り、パラメータを受け取る関数を返す関数。パラメータの数が十分な場合、元の関数が実行され、結果が返されます。

実装方法


簡単に考えれば、部分的な構成関数をカリー化するためのステップ数は fn のパラメーターの数に等しいことが分かります。これは、2 つのパラメーターを持つ plus 関数を 2 つのステップで部分的に構成する必要があることを意味します。 . fn.length が取得されます。

一般的な考え方は、パラメータが渡されるたびに、渡されるパラメータがない場合は、パラメータがパラメータ リスト argsList に入れられるということです。元のパラメータを返すために呼び出される関数の実行には、内部判定関数 _c(restNum, argsList) が必要です。1 つは残りのパラメータの数、もう 1 つは取得されたパラメータのリストです。パラメータ argsList; _c この関数は、渡されていないパラメータがあるかどうかを判断するためのものです。restNum が 0 の場合は、fn.apply(null, argsList) を通じて元の関数を実行し、存在する場合は結果を返します。渡す必要のあるパラメータ、つまり、restNum がゼロでない場合は、パラメータの受け取りを続けるために単一パラメータ関数

を返す必要があります。関数がパラメータを受け入れると、残りの必須パラメータの数が 1 つ減り、新しいパラメータが argsList に追加された後、パラメータの数が _c に渡されます。パラメータが不十分な場合は、新しいパラメータを受け取る役割を担う単一パラメータ関数が返されます。十分なパラメータがある場合は、元の関数が呼び出されて返されます。

それでは、それを見てみましょう:

function(x) {
 return _c(restNum - 1, argsList.concat(x));
}
ログイン後にコピー

ES6の記述方法は、配列の分割やアロー関数などのシンタックスシュガーを使用しているため、より簡単に見えますが、考え方は同じです~

function curry(fn) {
 function _c(restNum, argsList) {
  return restNum === 0 ?
   fn.apply(null, argsList) :
   function(x) {
    return _c(restNum - 1, argsList.concat(x));
   };
 }
 return _c(fn.length, []); // 递归开始
}
ログイン後にコピー

他の方法との比較


もう一つよく使われる方法がありますメソッド:

// ES6
const curry = fn => {
 const _c = (restNum, argsList) => restNum === 0 ?
  fn(...argsList) : x => _c(restNum - 1, [...argsList, x]);

 return _c(fn.length, []);
}
ログイン後にコピー

この記事で以前に説明したメソッドと比較すると、このメソッドには 2 つの問題があることがわかります。

性能稍差一点。

性能问题

做个测试:

console.time("curry");
const plus = curry((a, b, c, d, e) => a + b + c + d + e);
plus(1)(2)(3)(4)(5);
console.timeEnd("curry");
ログイン後にコピー

在我的电脑(Manjaro Linux,Intel Xeon E5 2665,32GB DDR3 四通道1333Mhz,Node.js 9.2.0)上:

本篇提到的方法耗时约 0.325ms

其他方法的耗时约 0.345ms

差的这一点猜测是闭包的原因。由于闭包的访问比较耗性能,而这种方式形成了两个闭包:fn 和 len,前面提到的方法只形成了 fn 一个闭包,所以造成了这一微小的差距。

相关推荐:

详解JavaScript函数柯里化

js柯里化的实例详解

javascript中有趣的反柯里化深入分析_基础知识

以上が絶妙な自動カリー化機能をJSで実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Doubaoアプリにはどのような機能がありますか? Doubaoアプリにはどのような機能がありますか? Mar 01, 2024 pm 10:04 PM

DoubaoアプリにはAI作成機能がたくさんあると思いますが、Doubaoアプリにはどのような機能があるのでしょうか?ユーザーはこのソフトウェアを使用して、絵画を作成したり、AI とチャットしたり、ユーザー向けの記事を生成したり、全員が曲を検索できるようにしたりすることができます。今回のDoubaoアプリの機能紹介では、具体的な操作方法をお伝えすることができますので、具体的な内容は以下の通りですので、ぜひご覧ください! Doubao アプリにはどのような機能がありますか? 回答: 絵を描いたり、チャットしたり、記事を書いたり、曲を検索したりできます。機能紹介: 1. 質問クエリ: AI を使用して質問に対する回答をより迅速に見つけることができ、あらゆる種類の質問をすることができます。 2. 画像生成: AI を使用して、一般的な要件を全員に伝えるだけで、全員に異なる画像を作成できます。 3. AIチャット:ユーザーのためにチャットできるAIを作成できます。

vivox100sとx100の違い:性能比較と機能分析 vivox100sとx100の違い:性能比較と機能分析 Mar 23, 2024 pm 10:27 PM

vivox100s と x100 携帯電話はどちらも vivo の携帯電話製品ラインの代表的なモデルであり、それぞれ異なる時代における vivo のハイエンド技術レベルを代表するものであるため、2 つの携帯電話にはデザイン、性能、機能に一定の違いがあります。この記事では、消費者が自分に合った携帯電話をより適切に選択できるように、これら 2 つの携帯電話を性能比較と機能分析の観点から詳しく比較します。まずはvivox100sとx100の性能比較を見てみましょう。 vivox100s には最新の機能が搭載されています。

セルフメディアとは一体何でしょうか?その主な特徴と機能は何ですか? セルフメディアとは一体何でしょうか?その主な特徴と機能は何ですか? Mar 21, 2024 pm 08:21 PM

インターネットの急速な発展に伴い、セルフメディアという概念が人々の心に深く根付いてきました。では、セルフメディアとは一体何でしょうか?その主な特徴と機能は何ですか?次に、これらの問題を 1 つずつ検討していきます。 1. セルフメディアとは何ですか? We-media は、その名前が示すように、あなたがメディアであることを意味します。これは、個人またはチームがインターネット プラットフォームを通じてコン​​テンツを独自に作成、編集、公開、配布できる情報媒体を指します。新聞、テレビ、ラジオなどの従来のメディアとは異なり、セルフメディアはよりインタラクティブでパーソナライズされており、誰もが情報の制作者および発信者になることができます。 2. セルフメディアの主な特徴と機能は何ですか? 1. 敷居が低い: セルフメディアの台頭により、メディア業界への参入の敷居が低くなり、煩わしい機材や専門チームは必要なくなりました。

小紅書アカウント管理ソフトウェアの機能は何ですか?小紅書アカウントを操作するにはどうすればよいですか? 小紅書アカウント管理ソフトウェアの機能は何ですか?小紅書アカウントを操作するにはどうすればよいですか? Mar 21, 2024 pm 04:16 PM

小紅書が若者の間で人気になるにつれ、ますます多くの人がこのプラットフォームを使用して、自分の経験や人生の洞察のさまざまな側面を共有し始めています。複数の小紅書アカウントを効果的に管理する方法が重要な問題となっています。この記事では、Xiaohongshu アカウント管理ソフトウェアの機能のいくつかについて説明し、Xiaohongshu アカウントをより適切に管理する方法を探ります。ソーシャルメディアが成長するにつれて、多くの人が複数のソーシャルアカウントを管理する必要があることに気づきます。これは小紅書ユーザーにとっても課題です。小紅書アカウント管理ソフトウェアの中には、コンテンツの自動公開、スケジュールされた公開、データ分析、その他の機能など、ユーザーが複数のアカウントをより簡単に管理できるようにするものがあります。これらのツールを通じて、ユーザーはアカウントをより効率的に管理し、アカウントの露出と注目を高めることができます。さらに、Xiaohongshu アカウント管理ソフトウェアには、

ディスカスとは何ですか? Discuzの定義と機能紹介 ディスカスとは何ですか? Discuzの定義と機能紹介 Mar 03, 2024 am 10:33 AM

「Discuz の探索: 定義、機能、およびコード例」 インターネットの急速な発展に伴い、コミュニティ フォーラムは人々が情報を取得し、意見を交換するための重要なプラットフォームになりました。多くのコミュニティ フォーラム システムの中でも、Discuz は中国でよく知られたオープン ソース フォーラム ソフトウェアとして、大多数の Web サイト開発者や管理者に好まれています。それで、ディスカスとは何ですか?どのような機能があり、Web サイトにどのように役立つのでしょうか?この記事では、Discuz について詳しく紹介し、読者がDiscuz についてさらに学ぶのに役立つ具体的なコード例を添付します。

PHP のヒント: 前のページに戻る関数をすばやく実装する PHP のヒント: 前のページに戻る関数をすばやく実装する Mar 09, 2024 am 08:21 AM

PHP のヒント: 前のページに戻る機能をすばやく実装する Web 開発では、前のページに戻る機能を実装する必要があることがよくあります。このような操作により、ユーザー エクスペリエンスが向上し、Web ページ間の移動が容易になります。 PHP では、いくつかの簡単なコードを通じてこの機能を実現できます。この記事では、前のページに戻る機能を素早く実装する方法と、具体的な PHP コード例を紹介します。 PHP では、$_SERVER['HTTP_REFERER'] を使用して前のページの URL を取得できます。

LinuxにおけるGDMの機能と機能を詳しく解説 LinuxにおけるGDMの機能と機能を詳しく解説 Mar 01, 2024 pm 04:18 PM

Linux での GDM の機能と機能の詳細な説明 Linux オペレーティング システムでは、GDM (GNOMEDisplayManager) は、ユーザーがシステムにログインおよびログアウトするためのインターフェイスを提供するグラフィカル ログイン マネージャーです。 GDM は通常、GNOME デスクトップ環境の一部ですが、他のデスクトップ環境でも使用できます。 GDM の役割は、ログイン インターフェイスを提供するだけでなく、ユーザー セッション管理、スクリーン セーバー、自動ログイン、その他の機能も含まれます。 GDM の機能には主に次の側面が含まれます。

Linux でのドライブの自動マウント Linux でのドライブの自動マウント Mar 20, 2024 am 11:30 AM

Linux オペレーティング システムを使用していて、システムが起動時にドライブを自動的にマウントするようにしたい場合は、デバイスの一意の識別子 (UID) とマウント ポイントのパスを fstab 構成ファイルに追加することでこれを行うことができます。 fstab は、/etc ディレクトリにあるファイル システム テーブル ファイルで、システムの起動時にマウントする必要があるファイル システムに関する情報が含まれています。 fstab ファイルを編集すると、システムを起動するたびに必要なドライブが正しくロードされるようになり、システムの安定した動作が保証されます。ドライバーの自動マウントはさまざまな場面で便利に使えます。たとえば、システムを外部ストレージ デバイスにバックアップする予定です。自動化を実現するには、起動時であってもデバイスがシステムに接続されたままであることを確認してください。同様に、多くのアプリケーションは直接

See all articles