网站搜索

javascript - 如果 Ramda 的 ifElse 抽象了三元运算,它是一个有效的模式吗


冒险的问题来表达观点。我正在一个使用 Ramda.js 的项目中工作。我在整个代码中看到许多 ifElse 调用。

const getEvent = R.ifElse(
  fireable,
  R.always(sendAnalyticsEvent),
  R.always(R.always(undefined))
);

真的值得把逻辑像这样包裹在函数式条件中吗?这样做有什么好处吗?

如果最终 Ramda 只是抽象了一个三元运算,并且在不匹配时返回 undefined。

Ramdas ifElse

var ifElse = _curry3(function ifElse(condition, onTrue, onFalse) {
  return curryN(Math.max(condition.length, onTrue.length, onFalse.length),
    function _ifElse() {
      return condition.apply(this, arguments) ? onTrue.apply(this, arguments) : onFalse.apply(this, arguments);
    }
  );
});
export default ifElse;

这似乎是函数式编程世界中的一种反模式,总是返回 undefined,或者在某些情况下返回 null

R.ifElse(hasUrl, promptToShare, R.always(null))

不管返回 undefined 是否有争议,使用三元运算符对于 JavaScript 社区来说不是更符合习惯用法吗?

hasUrl(urlObject) ? promptToShare() : null

这对我来说似乎更简洁、更易读,我想重构。但这可能是因为我对函数式编程世界的天真。

答案#1

几点说明(免责声明:我是 Ramda 的作者):

  • 你说得太对了。在 JavaScript 中,当新用户学习函数式编程时,无参数函数式代码被过度使用。我通常建议只有在它提高可读性的时候才有用。

  • ifElse 调用并不等同于 Javascript 条件表达式(三元运算符)。然而,它可以等同于返回三元运算符值的 lambda 函数。也就是说,这个例子更像 (urlObject) => hasUrl(urlObject) ? promptToShare(urlObject) : null。在这一点上,ifElse 至少可能更易读。这就引出了评论中关于部分应用/柯里化的观点。

  • 我几乎看不到使用 ifElse 配合具有不同签名的函数的理由。也就是说,如果 promptToShare 不接受任何参数,那么它可能不适合放在 ifElse 调用中。

  • 那个 getEvent 函数看起来相当奇怪。鉴于它使用了像 sendAnalyticsEvent 这样的名字,我猜它会产生一些副作用。而另一个分支则是无操作。虽然 Ramda 团队并不真正关心你如何使用这个库,但这并不是我们设想用户会用它创建的那种函数。

  • 我见过其他奇怪的对 ifElse 的调用,其中一个分支函数传入了恒等函数。那些应该大概被替换为 when 或 unless,这当然会更语义化。

所以我同意你的例子根本不需要 ifElse。但是 ifElse 及其同类 when 和 unless 确实有它们的用处。