機能的特徴
関数型プログラミングまたは関数型ライブラリを定義するものの明確な境界はありません。関数型言語のいくつかの機能はJavaScriptに組み込まれています。
- ファーストクラスの高階関数
- ラムダ/無名関数、クロージャー付き
他のものは、JavaScriptでいくつかの注意を払って達成することが可能です:
さらに、ES6の一部であり、現在、部分的または完全に利用可能なものもあります。
- コンパクトで簡潔な機能
- 末尾呼び出しの最適化によるパフォーマンスの高い再帰
そして、Javascriptの通常の範囲を本当に超えている他の多くがあります:
そうすれば、ライブラリーは、サポートしようとしている機能の種類を選んで選択することができ、それでも「機能的」と呼ぶことができます。
ファンタジーランド仕様
ファンタジーランドは、関数型プログラミングに数学カテゴリ理論と抽象代数学から移植された標準タイプの数のための仕様である、などの種類モノイド、関数形、およびモナド。これらのタイプはかなり抽象的で、おそらくより馴染みのある概念を拡張します。たとえば、ファンクタはmap
、関数を使用して移動できるコンテナであり、配列map
を使用して配列を移動できますArray.prototype.map
。
民話
Folktaleは、Fantasy-land仕様のさまざまな部分を実装するタイプのコレクションと、付随するユーティリティ関数の小さなコレクションです。これらのタイプは、Maybe、Either、Task(他の場所ではFutureと呼ばれるものと非常に似ており、Promiseのより適法ないとこ)とValidationのようなものです。
Folktaleは、Fantasy-land仕様の最もよく知られている実装であり、尊敬されています。しかし、決定的な実装やデフォルトの実装などはありません。fantasy-landは抽象型のみを指定し、コースの実装はそのような具象型を作成する必要があります。関数型ライブラリであるというFolktaleの主張は明らかです。これは、通常、関数型プログラミング言語で見られるデータ型を提供します。これにより、関数型のプログラミングが大幅に容易になります。
この例は、Folktaleのドキュメント(注意:最近のバージョンのドキュメントには含まれていません)からの抜粋で、これがどのように使用されるかを示しています。
// We load the library by "require"-ing it
var Maybe = require('data.maybe')
// Returns Maybe.Just(x) if some `x` passes the predicate test
// Otherwise returns Maybe.Nothing()
function find(predicate, xs) {
return xs.reduce(function(result, x) {
return result.orElse(function() {
return predicate(x)? Maybe.Just(x)
: /* otherwise */ Maybe.Nothing()
})
}, Maybe.Nothing())
}
var numbers = [1, 2, 3, 4, 5]
var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers)
// => Maybe.Just(3)
var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers)
// => Maybe.Nothing
ラムダ
Ramda(免責事項:私は作成者の1人です)は、非常に異なるタイプのライブラリーです。新しいタイプは提供されません。1 代わりに、既存の型の操作を簡単にする関数を提供します。これは、小さな関数を大きな関数に構成する、不変データを処理する、副作用を回避するという概念に基づいて構築されています。
Ramdaは特にリストで動作しますが、オブジェクトにも動作し、文字列にも動作します。また、Folktaleまたはその他のファンタジーランドの実装と相互運用できるように、その呼び出しの多くを委任します。例えば、RAMDAのmap
機能は、上の1と同様に動作するArray.prototype
ので、R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
。ただし、Folktale はマップも指定Maybe
するFantasy-land Functor
仕様を実装しているため、Ramdaを使用することもできますmap
。
R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
関数型ライブラリであるというRamdaの主張は、関数の作成を簡単にし、データを変更せず、純粋な関数のみを提示することにあります。Ramdaの一般的な使用法は、Ramdaの哲学に関する記事に見られるように、小さい関数を作成してより複雑な関数を構築することです。
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
その他の図書館
実際、私はより多くのライブラリーを見つけました、それらはすべて2つのカテゴリーに分類されるようです。アンダースコア、ロダッシュはラムダに非常に似ています。ファンタジーランド、ポイントフリーファンタジーは民話のようなものです。
それは本当に正確ではありません。まず第一に、Fantasy-landは、ライブラリがさまざまなタイプに実装することを決定できる仕様にすぎません。Folktaleは、その仕様の多くの実装の1つであり、おそらく最も総合的なものであり、確かに最も成熟したものの1つです。 ポイントフリーファンタジーとラムダファンタジーは他にもあり、他にもたくさんあります。
Underscoreとlodashは、見た目はRamdaに似ていますが、グラブバッグライブラリであり、Folktaleのようなものよりもまとまりのない多数の関数を提供します。そして、特定の機能でさえラムダの機能と重複することがよくあります。しかし、より深いレベルでは、ラムダはこれらのライブラリとは非常に異なる懸念を抱いています。Ramdaに最も近いいとこは、おそらくFKit、Fnuc、およびWu.jsなどのライブラリです。
Bilbyは独自のカテゴリに属し、Ramdaが提供するツールなどの多数のツールと、Fantasy-landと一致するいくつかのタイプの両方を提供しています。(ビルビーの作者は、ファンタジーランドの原作者でもあります。)
あなたの電話
これらのライブラリはすべて、機能的アプローチと機能的コミットメントの程度が大きく異なりますが、機能的と呼ばれる権利があります。
これらのライブラリのいくつかは、実際には一緒にうまく動作します。RamdaはFolktaleまたは他のFantasy-land実装でうまく機能するはずです。それらの懸念がほとんど重ならないため、それらは実際には競合しませんが、Ramdaは相互運用を比較的スムーズにするのに十分です。これは、選択できる他のいくつかの組み合わせではおそらくあまり当てはまりませんが、ES6のより単純な関数構文は、統合の手間をいくらか取り除くかもしれません。
ライブラリの選択、または使用するライブラリのスタイルさえも、プロジェクトと設定に依存します。利用できる優れたオプションはたくさんあり、その数は増えており、その多くは大幅に改善されています。JSで関数型プログラミングを行う良い機会です。
1さて、サイドプロジェクト、Folktaleと同じようなことをするラムダファンタジーがありますが、それはコアライブラリの一部ではありません。