Javascript 什么是我的应用函子不与Ramda';美联社?
我试图学习如何在javascript中使用应用程序函子,并遇到了Javascript 什么是我的应用函子不与Ramda';美联社?,javascript,functional-programming,ramda.js,applicative,Javascript,Functional Programming,Ramda.js,Applicative,我试图学习如何在javascript中使用应用程序函子,并遇到了ap方法。我尝试使用它来组合三个阵列,如下所示: const products = ['teeshirt', 'sweater'] const options = ['large', 'medium', 'small'] const colors = ['red', 'black'] 因此,根据我正在尝试的: const buildMerch = product => option => color =>`${p
ap
方法。我尝试使用它来组合三个阵列,如下所示:
const products = ['teeshirt', 'sweater']
const options = ['large', 'medium', 'small']
const colors = ['red', 'black']
因此,根据我正在尝试的:
const buildMerch = product => option => color =>`${product}-${option}-${color}`
const merchandise = R.ap([buildMerch], [products, options, colors])
但这给了我三个功能:
[function (option) {
return function (color) {
return product + '-' + option + '-' + color;
};
}, function (option) {
return function (color) {
return product + '-' + option + '-' + color;
};
}, function (option) {
return function (color) {
return product + '-' + option + '-' + color;
};
}]
…而不是我期望的阵列的组合结果:
["teeshirt- large-red", "teeshirt- large-black", "teeshirt- medium-red", "teeshirt- medium-black", "teeshirt- small-red", "teeshirt- small-black", "sweater- large-red", "sweater- large-black", "sweater- medium-red", "sweater- medium-black", "sweater- small-red", "sweater- small-black"]
我做错了什么?我该如何解决这个问题
下面是一个jsbin,其中有一个问题:
ap
根据文档将函数列表应用于值列表。您的函数buildMerch
具有以下“类型”:
最简单的ap
是map
:对于任何应用函子,我们得到:
pure f <*> a
======
map f a
通过在参数列表上映射buildMerch
,我们可以部分地将其应用于所讨论的数组。实现所需功能的表达式是:
const merchandise = R.ap(R.ap(R.map(buildMerch, products), options), colors);
首先,我们在产品阵列上映射
buildMerch
。这为我们提供了一个包含两个参数的函数数组:[String->String->String]
。然后,我们使用R.ap
将其与选项组合::[String]
,它将第一个数组中的每个函数应用于选项
数组中的每个参数。现在我们有了[String->String]
,最后我们使用颜色的R.ap
来获得您想要的字符串的最终数组。将函数列表应用于值列表。在您的情况下,您将使用指定数组中的每个元素调用buildMerch
,即products
,然后使用options
,然后使用colors
,而不是数组中的每个组合。这与您的方法签名不匹配,您需要三个参数。解决此问题的另一种方法是将ap
添加到本机javascript数组中。通过这种方式,您实际上是将数组转化为一个应用程序函子,您不需要库,并且它与您可能想要使用的任何其他应用程序函子使用相同的接口
// add ap
Array.prototype.ap = function(anotherArray) {
return this.map(el =>
anotherArray.map(el)
).flatten();
};
这依赖于展平(或“连接”)
现在:
现在,您还可以提起所有三个:
const liftA3 = (fn, functor1, functor2, functor3) =>
functor1.map(fn).ap(functor2).ap(functor3);
liftA3(buildMerch, products, options, colors) // also returns merchandise
// add ap
Array.prototype.ap = function(anotherArray) {
return this.map(el =>
anotherArray.map(el)
).flatten();
};
// add flatten
Array.prototype.flatten = function() {
let results = [];
this.forEach(subArray => {
subArray.forEach(item => {
results.push(item);
});
});
return results;
};
const products = ['teeshirt', 'sweater'];
const options = ['large', 'medium', 'small'];
const colors = ['red', 'black'];
const buildMerch = product => option => color =>`${product}-${option}-${color}`;
const merchandise = products.map(buildMerch).ap(options).ap(colors);
const liftA3 = (fn, functor1, functor2, functor3) =>
functor1.map(fn).ap(functor2).ap(functor3);
liftA3(buildMerch, products, options, colors) // also returns merchandise