我正在通过阅读DrBoolean的book来学习javascript FP。
我四处寻找函数式编程库。我找到了Ramda和Folktale。两者都声称是函数式编程库。
但他们是如此不同:
Ramda似乎包含用于处理列表的实用函数:map,reduce,filter和pure函数:curry,compose。它不包含任何处理monad,functor的东西。
Folktale但是不包含列表或函数的任何实用程序。它似乎在jad中实现了一些代数结构,比如monad:Maybe,Task ...
实际上我找到了更多的图书馆,它们似乎都属于这两个类别。下划线,lodash非常喜欢Ramda。梦幻之地,无点幻想就像民间故事一样。
这些非常不同的库可以被称为功能,如果是这样,是什么使每个库成为一个功能库?
答案 0 :(得分:153)
定义函数式编程或函数库没有明确的界限。功能语言的一些功能内置于Javascript中:
其他人可以在Javascript中小心完成:
还有一些是ES6的一部分,现在部分或完全可用:
还有很多其他的东西超出了Javascript的正常范围:
然后,图书馆可以挑选和选择它试图支持的功能,并且仍然合理地被称为“功能性”#34;
Fantasy-land是从数学类别理论和抽象代数移植到函数式编程的许多标准类型的规范,类型包括Monoid,Functor和{{3} }。这些类型相当抽象,可能会延伸更熟悉的概念。例如,函数是可以map
使用函数进行操作的容器,使用map
可以Array.prototype.map
使用// 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
数组。
Monad是实现Fantasy-land规范各个部分的类型集合,以及一小部分伴随效用函数。这些类型包括Folktale,Maybe,Either(非常类似于其他地方称为Future,以及更为合法的表兄弟)和Task < / p>
Folktale可能是Fantasy-land规范中最着名的实现,并且备受推崇。但是没有明确或默认的实施; fantasy-land只指定抽象类型,当然实现必须创建这样的具体类型。 Folktale声称自己是一个功能库很明显:它提供了通常在函数式编程语言中找到的数据类型,这些类型使得以函数方式编程变得更加容易。
此示例来自Validation,显示了如何使用它:
map
Folktale documentation(免责声明:我是其中一位作者)是一种非常不同类型的图书馆。它没有为您提供新类型。 1 相反,它提供的功能使其更容易在现有类型上操作。它围绕将较小的函数组合成较大的函数,使用不可变数据,避免副作用的概念构建。
Ramda尤其在列表上运行,但也在对象上运行,有时在字符串上运行。它还以这样一种方式委托它的许多调用,它将与Folktale或其他Fantasy-land实现互操作。例如,Ramda的Array.prototype
函数与R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
上的函数类似,因此Maybe
。但是因为Folktale的Functor
实现了Fantasy-land map
规范,它也指定了地图,你也可以使用Ramda的R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
:
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
Ramda声称自己是一个功能库,可以轻松编写功能,从不改变数据,只提供纯函数。 Ramda的典型用法是通过组合较小的函数来构建更复杂的函数,如Ramda
中的文章所示。{{1}}
实际上我找到了更多的图书馆,它们似乎都属于这两个类别。下划线,lodash非常喜欢Ramda。梦幻之地,无点幻想就像民间故事一样。
那不太准确。首先,Fantasy-land只是图书馆可以决定为各种类型实施的规范。 Folktale是该规范的众多实现之一,可能是最全面的,当然是最成熟的。 philosphy of Ramda和Pointfree-fantasy是其他人,有ramda-fantasy。
many more和Underscore表面上看起来像是Ramda,因为它们是抓包式库,提供了大量的功能,其内聚力远远低于Folktale。甚至特定的功能也经常与Ramda的重叠。但在更深层次上,Ramda对这些图书馆的关注度却截然不同。拉姆达最亲近的堂兄弟可能是lodash,FKit和Fnuc等图书馆。
Wu.js属于它自己的类别,提供了许多工具,例如Ramda提供的工具和一些与Fantasy-land一致的类型。 (Bilby的作者也是Fantasy-land的原作者。)
所有这些库都有权被称为功能性,尽管它们在功能方法和功能承诺程度上差异很大。
其中一些库实际上可以很好地协同工作。 Ramda应该与Folktale或其他Fantasy-land实施很好地配合。由于他们的担忧几乎没有重叠,他们真的不会发生冲突,但Ramda确实足以使互操作相对平稳。对于您可以选择的其他一些组合来说,这可能不太正确,但ES6的简单函数语法也可能会带来一些集成的痛苦。
库的选择,甚至是要使用的库的样式,将取决于您的项目和您的偏好。有很多好的选择,而且数量正在增长,其中许多都在大大改善。现在是在JS中进行函数式编程的好时机。
1 嗯,有一个侧面项目,Bilby做类似于Folktale的工作,但它不是核心库的一部分。