【问题标题】:Chaining and Function Composition链接和函数组合
【发布时间】:2018-08-21 18:12:32
【问题描述】:

这是我试图理解的一段代码:

const seq2 = (f1, f2) => {
 return (...args) => {

  return f2( f1( ...args) );
 }
}



const seq = ( f1, ...fRest) =>
 fRest.reduce( seq2, f1 );

const elevator = {
 floor: 5
};

const up = elevator => {
 return {
  floor: elevator.floor + 1
 }
};

const down = elevator => {
 return {
  floor: elevator.floor - 1
 }
};


const move = seq( up, up, down, up);
const newElevator = move( elevator );



console.log( newElevator.floor ) // shows 7

这是一个来自 js 函数式编程课程的例子。我想弄清楚我是否可以简化 seq 函数,让它看起来像这样

const seq = ( ...fRest) => fRest.reduce( seq2 );

??????

是否有任何具体原因我必须将f1 作为第一个参数传递,然后将其作为initialValue 进一步传递给reduce 方法?当我不在 reduce 方法中指定 initialValue 时,它不会默认将第一个数组元素 - accumulator - 视为 initialValue 吗?如果有人可以向我解释该代码中发生了什么,我将不胜感激:)

【问题讨论】:

  • 你试过了吗?它正在工作
  • 是的,它正在工作。但是不知道作者用f1参数写这个函数是有原因的吗??
  • 我不认为这背后有什么特别的原因。也许他不知道你能做到。也许这就是他喜欢使用reduce 的方式。反正两者都是一样的。
  • @ibrahimmahrir 在没有初始累加器的情况下减少是无效的
  • 如果这是您直接从课程材料中提取的代码,那么无论是谁编写的,都应该为参数/变量提供更具描述性的名称。

标签: javascript functional-programming chaining function-composition


【解决方案1】:

seq() 会尝试在没有累加器的情况下减少空数组,这是一个错误 - 并不是 f1 按作者在此处所写的方式解决了这个问题。

initialValue – 用作callback 第一次调用的第一个参数的值。如果未提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用 reduce() 是错误的 – 源 MDN:Array.prototype.reduce

seq 的更健壮的实现在使用seq() 构建空序列时不会导致错误

const identity = x =>
  x

const seq2 = (f, g) =>
  (...args) => f (g (...args))

const seq = (f = identity, ...rest) =>
  rest.reduce (seq2, f)

const up = elevator =>
  ({ floor: elevator.floor + 1 })
  
const down = elevator =>
  ({ floor: elevator.floor - 1 })

console.log
 ( seq (up, up, down, up) ({ floor: 3 }) // { floor: 5 }
 , seq () ({ floor: 3 })                 // { floor: 3 }
 )

seq 的简化版本,通过禁止可变参数函数的组合来促进更好的功能卫生

const identity = x =>
  x

const seq = (f = identity, ...rest) =>
  f === identity
    ? f
    : x => seq (...rest) (f (x))

const up = elevator =>
  ({ floor: elevator.floor + 1 })
  
const down = elevator =>
  ({ floor: elevator.floor - 1 })

console.log
 ( seq (up, up, down, up) ({ floor: 3 }) // { floor: 5 }
 , seq () ({ floor: 3 })                 // { floor: 3 }
 )

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多