web-dev-qa-db-ja.com

なぜ民話とラムダはそんなに違うのですか?

DrBooleanの book を読んで、javascript FPを学習しています。

関数型プログラミングライブラリを検索しました。 RamdaとFolktaleを見つけました。どちらも関数型プログラミングライブラリであると主張しています。

しかし、それらは非常に異なっています:

  • Ramda は、リストを処理するためのユーティリティ関数:map、reduce、filter、および純粋な関数:curry、composeを含むようです。モナド、ファンクターに対処するものは何も含まれていません。

  • Folktale ただし、リストまたは機能用のユーティリティは含まれていません。モナドのようなjavascriptでいくつかの代数構造を実装しているようです:たぶん、タスク...

実際、私はさらに多くのライブラリを見つけました。それらはすべて2つのカテゴリに分類されるようです。下線、lodashはRamdaに非常に似ています。ファンタジーランド、ポイントフリーファンタジーは民話のようなものです。

これらの非常に異なるライブラリを両方ともfunctionalと呼ぶことができますか?

80
Aaron Shen

機能的特徴

関数型プログラミングまたは関数型ライブラリを定義するものの明確な境界はありません。関数型言語のいくつかの機能はJavascriptに組み込まれています。

  • 一流の高階関数
  • ラムダ/匿名関数、クロージャー付き

Javascriptでいくつかの注意を払って達成できるものもあります。

  • 不変性
  • 参照の透明性

さらに他のものはES6の一部であり、現在部分的または完全に利用可能です:

  • コンパクトで簡潔な機能
  • 末尾呼び出しの最適化によるパフォーマンスの再帰

また、Javascriptの通常の範囲をはるかに超える他の多くのものがあります。

  • パターンマッチング
  • 遅延評価
  • 同質性

したがって、ライブラリは、サポートしようとしている機能の種類を選択できますが、それでも合理的に「機能的」と呼ばれます。

ファンタジーランド仕様

Fantasy-land は、数学的なカテゴリ理論と抽象代数から関数型プログラミングに移植された多くの標準タイプの仕様です。 モノイドファンクター などのタイプおよび モナド 。これらのタイプはかなり抽象的であり、おそらくより馴染みのある概念を拡張します。例えば、ファンクターは、関数でmappedすることができるコンテナーであり、配列は_Array.prototype.map_を使用してmappedすることができます。

民話

Folktale は、Fantasy-land仕様のさまざまな部分を実装する型のコレクションと、付随するユーティリティ関数の小さなコレクションです。これらのタイプは、 たぶんいずれかタスク (他の場所でフューチャーと呼ばれるものに非常に似ており、Promiseのより合法的な従兄弟)と 検証

民話は、おそらくファンタジーランド仕様の最もよく知られた実装であり、尊敬されています。しかし、決定的な実装やデフォルトの実装などはありません。 fantasy-landは抽象型のみを指定し、もちろん実装ではそのような具象型を作成する必要があります。 Folktaleの関数型ライブラリであるという主張は明確です。これは、関数型プログラミング言語で一般的に見られるデータ型を提供し、関数型のプログラミングを大幅に容易にします。

Folktale documentation のこの例は、それがどのように使用されるかを示しています。

_// 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関数は、_Array.prototype_の関数と同様に動作するため、R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]です。ただし、FolktaleのMaybeは、ファンタジーランドFunctor仕様(マップも指定)を実装しているため、Ramdaのmapを使用することもできます。

_R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
_

関数型ライブラリーであるというラムダの主張は、関数の構成を簡単にし、データを変更せず、純粋な関数のみを提示することにあります。 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つのカテゴリに分類されるようです。下線、lodashはRamdaに非常に似ています。ファンタジーランド、ポイントフリーファンタジーは民話のようなものです。

それは本当に正確ではありません。まず、Fantasy-landは、ライブラリがさまざまなタイプに実装することを決定できる単なる仕様です。 Folktaleは、その仕様の多くの実装の1つであり、おそらく最もバランスのとれたものであり、確かに最も成熟したものの1つです。 Pointfree-fantasy および ramda-fantasy は他のものであり、 さらに多くの があります。

アンダースコア および lodash は表面的にはRamdaに似ており、グラブバッグライブラリであり、Folktaleのようなものよりもまとまりのない多数の関数を提供します。また、特定の機能でさえ、ラムダの機能と重複することがよくあります。しかし、より深いレベルでは、ラムダはそれらのライブラリとは非常に異なる懸念を持っています。 Ramdaの最も近いいとこは、おそらく FKitFnuc 、および Wu.js のようなライブラリです。

Bilby は独自のカテゴリに属し、Ramdaが提供するツールや、Fantasy-landと一致するいくつかのタイプのツールを提供します。 (Bilbyの作者はFantasy-landの原作者でもあります。)

あなたの電話

これらのライブラリはすべて機能的と呼ばれる権利を持っていますが、機能的アプローチと機能的コミットメントの程度は大きく異なります。

これらのライブラリのいくつかは、実際にはうまく機能します。 Ramdaは、Folktaleやその他のファンタジーランドの実装でうまく機能するはずです。彼らの懸念はほとんど重ならないため、実際には競合しませんが、Ramdaは相互運用を比較的スムーズにするのに十分なだけです。これはおそらく、選択できる他の組み合わせのいくつかには当てはまりませんが、ES6のより単純な関数構文は、統合の苦痛の一部を取り除くかもしれません。

ライブラリの選択、または使用するライブラリのstyleでさえ、プロジェクトと好みに依存します。多くの優れたオプションが利用可能であり、その数は増え続けており、それらの多くは大幅に改善されています。 JSで関数型プログラミングを行う良い機会です。


1まあ、サイドプロジェクト、 ramda-fantasy があります。Folktaleがやっていることと似たようなことをしていますが、コアライブラリの一部ではありません。

157
Scott Sauyet