为什么 folktale 和 ramda 如此不同?
why are folktale and ramda so different?
我正在通过阅读 DrBoolean 的 book 来学习 javascript 函数式编程。
我四处搜索函数式编程库。我找到了 Ramda 和 Folktale。两者都声称是函数式编程库。
但它们是如此不同:
Ramda 似乎包含处理列表的实用函数:map、reduce、filter 和纯函数:curry、compose。它不包含任何处理 monad、functor 的内容。
Folktale 但是不包含列表或函数的任何实用程序。它似乎在 javascript 中实现了一些代数结构,例如 monad: Maybe, Task...
其实我找的库比较多,好像都属于这两类。 Underscore 和 lodash 就像 Ramda。幻想世界,无点幻想就像民间故事。
能否将这些截然不同的库都称为功能性,如果可以,是什么让每个库都成为功能性库?
功能特点
函数式编程或函数式库的定义没有明确的界限。 Javascript:
内置了一些函数式语言的特性
- 一阶-class、高阶函数
- Lambdas/Anonymous 个函数,带闭包
其他可以在 Javascript 中小心完成:
- 不变性
- 引用透明度
还有一些是 ES6 的一部分,现在部分或全部可用:
- 紧凑,甚至简洁的函数
- 通过尾调用优化实现高性能递归
还有很多其他的确实超出了 Javascript 的正常范围:
- 模式匹配
- 惰性评价
- 同像性
然后,一个图书馆可以选择它试图支持的功能种类,并且仍然可以合理地称为“功能性”。
梦幻乐园规格
Fantasy-land is a specification for a number of the standard types ported from mathematical Category Theory and Abstract Algebra to functional programming, types such as Monoid, Functor, and Monad。这些类型相当抽象,并且可能扩展了更熟悉的概念。例如,仿函数是可以用函数 map
覆盖的容器,就像使用 Array.prototype.map
.
可以 map
覆盖数组一样
民间故事
Folktale is a collection of types implementing various parts of the Fantasy-land specification and a small collection of companion utility functions. These types are things like Maybe, Either, Task (very similar to what is elsewhere called a Future, and a more lawful cousin to a Promise), and Validation
Folktale 可能是 Fantasy-land 规范最著名的实现,并且备受推崇。但是没有确定的或默认的实现这样的东西; 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 相反,它提供的功能可以更轻松地对现有类型进行操作。它是围绕将较小的函数组合成较大的函数、使用不可变数据以及避免副作用的概念构建的。
Ramda 尤其适用于列表,但也适用于对象,有时适用于字符串。它还以与 Folktale 或其他 Fantasy-land 实现互操作的方式委托其许多调用。例如,Ramda 的 map
函数与 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 的典型用法是通过组合较小的函数来构建更复杂的函数,如 philosphy of Ramda
上的一篇文章所示
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
其他图书馆
Actually I found more libraries, they all seem fall into the two categorys. underscore, lodash are very like Ramda. Fantasy-land, pointfree-fantasy are like folktale.
这不太准确。首先,Fantasy-land 只是图书馆可以决定为各种类型实施的规范。 Folktale 是该规范的众多实现之一,可能是最全面的实现之一,当然也是最成熟的实现之一。 Pointfree-fantasy and ramda-fantasy are others, and there are many more.
Underscore and lodash are superficially like Ramda in that they are grab-bag libraries, providing a great number of functions with much less cohesion than something like Folktale. And even the specific functionality often overlaps with Ramda's. But at a deeper level, Ramda has very different concerns from those libraries. Ramda's closest cousins are probably libraries like FKit, Fnuc, and Wu.js.
Bilby自成一类,既提供了一些工具,例如Ramda提供的工具,也提供了一些与Fantasy-land一致的类型。 (Bilby的作者也是Fantasy-land的原作者。)
你来电
所有这些库都有权称为功能性库,尽管它们在功能性方法和功能承诺程度方面差异很大。
其中一些库实际上可以很好地协同工作。 Ramda 应该可以很好地与 Folktale 或其他 Fantasy-land 实现配合使用。由于他们的关注点几乎没有重叠,所以他们实际上并不冲突,但 Ramda 所做的足以使互操作相对顺利。对于您可以选择的其他一些组合,这可能不太正确,但 ES6 更简单的函数语法也可以减轻集成的一些痛苦。
库的选择,甚至样式 要使用的库,将取决于您的项目和您的偏好。有很多不错的选择,而且数量还在增加,其中许多都在大大改进。现在是用 JS 进行函数式编程的好时机。
1好吧,有一个副项目,ramda-fantasy 做一些类似于 Folktale 所做的事情,但它不是核心库的一部分。
我正在通过阅读 DrBoolean 的 book 来学习 javascript 函数式编程。
我四处搜索函数式编程库。我找到了 Ramda 和 Folktale。两者都声称是函数式编程库。
但它们是如此不同:
Ramda 似乎包含处理列表的实用函数:map、reduce、filter 和纯函数:curry、compose。它不包含任何处理 monad、functor 的内容。
Folktale 但是不包含列表或函数的任何实用程序。它似乎在 javascript 中实现了一些代数结构,例如 monad: Maybe, Task...
其实我找的库比较多,好像都属于这两类。 Underscore 和 lodash 就像 Ramda。幻想世界,无点幻想就像民间故事。
能否将这些截然不同的库都称为功能性,如果可以,是什么让每个库都成为功能性库?
功能特点
函数式编程或函数式库的定义没有明确的界限。 Javascript:
内置了一些函数式语言的特性- 一阶-class、高阶函数
- Lambdas/Anonymous 个函数,带闭包
其他可以在 Javascript 中小心完成:
- 不变性
- 引用透明度
还有一些是 ES6 的一部分,现在部分或全部可用:
- 紧凑,甚至简洁的函数
- 通过尾调用优化实现高性能递归
还有很多其他的确实超出了 Javascript 的正常范围:
- 模式匹配
- 惰性评价
- 同像性
然后,一个图书馆可以选择它试图支持的功能种类,并且仍然可以合理地称为“功能性”。
梦幻乐园规格
Fantasy-land is a specification for a number of the standard types ported from mathematical Category Theory and Abstract Algebra to functional programming, types such as Monoid, Functor, and Monad。这些类型相当抽象,并且可能扩展了更熟悉的概念。例如,仿函数是可以用函数 map
覆盖的容器,就像使用 Array.prototype.map
.
map
覆盖数组一样
民间故事
Folktale is a collection of types implementing various parts of the Fantasy-land specification and a small collection of companion utility functions. These types are things like Maybe, Either, Task (very similar to what is elsewhere called a Future, and a more lawful cousin to a Promise), and Validation
Folktale 可能是 Fantasy-land 规范最著名的实现,并且备受推崇。但是没有确定的或默认的实现这样的东西; 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 相反,它提供的功能可以更轻松地对现有类型进行操作。它是围绕将较小的函数组合成较大的函数、使用不可变数据以及避免副作用的概念构建的。
Ramda 尤其适用于列表,但也适用于对象,有时适用于字符串。它还以与 Folktale 或其他 Fantasy-land 实现互操作的方式委托其许多调用。例如,Ramda 的 map
函数与 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 的典型用法是通过组合较小的函数来构建更复杂的函数,如 philosphy of Ramda
上的一篇文章所示// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
其他图书馆
Actually I found more libraries, they all seem fall into the two categorys. underscore, lodash are very like Ramda. Fantasy-land, pointfree-fantasy are like folktale.
这不太准确。首先,Fantasy-land 只是图书馆可以决定为各种类型实施的规范。 Folktale 是该规范的众多实现之一,可能是最全面的实现之一,当然也是最成熟的实现之一。 Pointfree-fantasy and ramda-fantasy are others, and there are many more.
Underscore and lodash are superficially like Ramda in that they are grab-bag libraries, providing a great number of functions with much less cohesion than something like Folktale. And even the specific functionality often overlaps with Ramda's. But at a deeper level, Ramda has very different concerns from those libraries. Ramda's closest cousins are probably libraries like FKit, Fnuc, and Wu.js.
Bilby自成一类,既提供了一些工具,例如Ramda提供的工具,也提供了一些与Fantasy-land一致的类型。 (Bilby的作者也是Fantasy-land的原作者。)
你来电
所有这些库都有权称为功能性库,尽管它们在功能性方法和功能承诺程度方面差异很大。
其中一些库实际上可以很好地协同工作。 Ramda 应该可以很好地与 Folktale 或其他 Fantasy-land 实现配合使用。由于他们的关注点几乎没有重叠,所以他们实际上并不冲突,但 Ramda 所做的足以使互操作相对顺利。对于您可以选择的其他一些组合,这可能不太正确,但 ES6 更简单的函数语法也可以减轻集成的一些痛苦。
库的选择,甚至样式 要使用的库,将取决于您的项目和您的偏好。有很多不错的选择,而且数量还在增加,其中许多都在大大改进。现在是用 JS 进行函数式编程的好时机。
1好吧,有一个副项目,ramda-fantasy 做一些类似于 Folktale 所做的事情,但它不是核心库的一部分。