为什么民间故事和ramda如此不同?

通过阅读DrBoolean的书,我正在学习JavaScript FP。

我search了function性编程库。 我find了拉姆达和民间故事。 两者都声称是function性编程库。

但他们是如此不同:

  • Ramda似乎包含了处理list的实用函数:map,reduce,filter和pure functions:curry,compose。 它不包含任何处理monad,functor的东西。

  • 然而民间故事不包含任何列表或function的实用程序。 它似乎实现了一些代数结构在JavaScript像monad:也许,任务…

实际上我发现了更多的图书馆,它们似乎都属于这两个范畴。 下划线,lodash非常喜欢拉姆达。 幻想世界,无点幻想就像民间故事。

这两个非常不同的图书馆可以称为function ,如果是这样,是什么使每个图书馆function?

function特点

定义函数式编程或函数式库的界限并不清晰。 函数式语言的一些特征被embedded到Javascript中:

  • 一stream的高阶function
  • Lambdas /匿名函数,closures

其他一些可以用Javascript来完成,

  • 不变性
  • 参照透明度

还有一些是ES6的一部分,现在部分或完全可用:

  • 紧凑,甚至简洁的function
  • 通过尾部呼叫优化的性能recursion

还有很多其他的超出了Javascript的正常范围:

  • 模式匹配
  • 懒惰的评价
  • 同像性

然后,一个图书馆可以挑选和试图支持哪些function,并且仍然被合理地称为“function性”。

幻想土地规格

Fantasy-land是从math分类理论和抽象代数到函数式编程(例如Monoid , Functor和Monad)的标准types的规范。 这些types是相当抽象的,并可能扩展更为熟悉的概念。 例如,函子是可以用函数map容器,也可以是使用Array.prototype.map map数组的方式。

民间故事

民间故事是一个实现幻想土地规范的各个部分的types的集合,以及伴随实用函数的一个小集合。 这些types是可能 , 无论是任务 (非常类似于其他地方称为未来,和一个更合法的表哥承诺)和validation

“民间故事”也许是“梦幻地”规范中最着名的一个实现,并且受到了广泛的尊重。 但是不存在明确的或默认的实现; 幻想土地只是指定抽象types,当然一个实现必须创build这样的具体types。 Folktale声称作为一个函数库是很明显的:它提供了通常在函数式编程语言中find的数据types,这使得它在function上更容易编程。

这个例子来自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

拉姆达 (免责声明:我是其中一位作者)是一个非常不同types的图书馆。 它不为您提供新的types。 1而是提供了使现有types更容易操作的function。 它是围绕着将较小的function组合成较大的function,处理不可变数据以及避免副作用的概念而构build的。

拉姆达特别在列表上运行,但也在对象上,有时在string上运行。 它也以这样一种方式委托了它的许多电话,它将与Folktale或其他幻想地实现互操作。 例如,Ramda的map函数与Array.prototype类似,所以R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16] 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的典型用法是通过组合更小的组合来构build更复杂的function,如Ramda哲学论文

 // :: [Comment] -> [Number] var userRatingForComments = R.pipe( R.pluck('username') // [Comment] -> [String] R.map(R.propOf(users)), // [String] -> [User] R.pluck('rating'), // [User] -> [Number] ); 

其他图书馆

其实我find了更多的图书馆,他们似乎都落入了两个范畴。 下划线,lodash非常喜欢拉姆达。 幻想世界,无点幻想就像民间故事。

这并不准确。 首先,幻想土地只是图书馆可以决定实施的各种types的规范。 Folktale是该规范的许多实现之一,可能是最为成熟的一个,也是最成熟的。 自由幻想和幻想幻想是其他的,还有更多 。

下划线和lodash表面上就像拉姆达一样,它们是抓包袋的图书馆,提供了大量的function,而且比起Folktale这样的内聚力要小得多。 而且即使是特定的function也经常与拉达的重叠。 但在更深层次上,拉姆达与这些图书馆有着非常不同的担忧。 拉姆达最亲密的表兄可能是像FKit , Fnuc和Wu.js这样的图书馆 。

Bilby属于自己的一类,提供了Ramda提供的一些工具,以及一些与Fantasy-land一致的types。 (Bilby的作者也是Fantasy-land的原作者。)

你的来电

所有这些图书馆都有权被称为function,虽然它们在function方法和function承诺程度上差异很大。

其中一些库实际上可以很好地协同工作。 拉姆达应该与Folktale或其他幻想土地实施。 由于他们的担心几乎没有重叠,他们真的没有冲突,但拉姆达恰恰足以使互操作相对平稳。 对于你可以select的其他组合来说,这可能不是那么正确,但是ES6更简单的函数语法也可能会带来一些整合的痛苦。

图书馆的select,甚至是图书馆的风格 ,都将取决于你的项目和你的喜好。 有很多很好的select,数量正在增长,其中许多正在大大改善。 在JS中进行函数式编程是个好时机。


1那么,有一个副项目, ramda幻想做类似于民间故事,但它不是核心图书馆的一部分。