如何构建一个装饰器,用于多元化curried函数的最终参数?

时间:2014-12-19 18:58:39

标签: javascript functional-programming

我试图用JavaScript编写函数库。我还使用lodash

到目前为止,我抽象地得到了什么:

x = _.curry(function(property, data) {
  return data.get(property);
});

有了这个,你可以x(1)(2)x(1, 2),一切都按预期工作。

说我想修改函数,使它data可以是一个数组:

x = _.curry(function(property, data) {
  if (_.isArray(data)) {
    return _.map(data, x(property));
  } else {
    return item.get(property);
  }
});

现在效果很好。但我有30多个功能。对于每个函数,必须有一个比手动if (_.isArray(data)... else...更好的方法。装饰师可能吗?

decorate = function(func) {
  // return a curried func and handle the aforementioned _.isArray
}

x = decorate(function(property, data) {
  if (_.isArray(data)) {
    return _.map(data, x(property));
  } else {
    return item.get(property);
  }
});

我完全迷失了如何编写装饰功能:一个可以采用arity 2和arity 3功能进行装饰的功能。

2 个答案:

答案 0 :(得分:0)

我不确定你想要完成什么,但是这样的工作可能吗?这有点hacky但想法是从外部传递函数。

x = _.curry(function(func, data) {
 return _.map(_.flatten([data]), func);
});

答案 1 :(得分:0)

首先用一个映射数组参数的原始函数包装原始函数,然后你就可以调整那个包装版本。

var decorate = function(func) {
    var mapIfArray = function(property, data) {
        if (_.isArray(data)) {
            return _.map(data, _.curry(func)(property));
        } else {
            return func(property, data);
        }
    }

    return _.curry(mapIfArray);
}

您可以这样使用它:

var undecorated = function(property, data) {
    return data.get(property);
}

var decorated = decorate(undecorated);

假设所有未修饰的函数都是arity 2,最后可能是数组。如果不是这种情况,你要么必须为不同的arities创建不同的装饰器,要么使用arguments对象做某种伏都教。