简体   繁体   English

JavaScript currying函数

[英]Javascript currying function

I am having a problem with one of the assignments in my javascript programming course. 我的javascript编程课程中的作业之一有问题。

Assignment: 分配:

Create a function called "calculate" which expects three functions as parameters and when called returns one of those functions as a result. 创建一个名为“计算”的函数,该函数期望将三个函数用作参数,并在调用时返回这些函数之一作为结果。

Everytime you call 每次打电话

 let result = calculate(add, subtract, multiply)(1,3) 

it should return a different result. 它应该返回不同的结果。

I have tried different approaches and got different errors like calcuate is not a function or multiply is not defined. 我尝试了不同的方法,并得到了不同的错误,例如计算不是函数或未定义乘法。

This is what I have tried so far: 到目前为止,这是我尝试过的:

function add(num1, num2){
  return num1 + num2;
}

function subtract(num1, num2){
  return num1 - num2;
}

function multiply(num1, num2){
  return num1 * num2;
}

function calculate(add, subtract, multiply){

  let randNum = Math.floor(Math.random() * 3) + 1

  switch(randNum){
    case 1:
      let add = add(num1, num2)
      break;

    case 2:
      let subtract = subtract(num1, num2);
      break;

    case 3:
      let multiply = multiply(num1, num2);
      break;

  }

}

let result = calculate(add(2,4), subtract(2,4), multiply(2,4))
console.log(result);

I did some research on currying, but I can't see what I am getting wrong. 我对curry进行了一些研究,但看不到我错了。 Any help would be gratefully appreciated. 任何帮助将不胜感激。

You could take a random function from the arguments and return this function for another call with parameters. 您可以从参数中获取随机函数,然后将此函数返回以进行另一个带参数的调用。

 const add = (a, b) => a + b, subtract = (a, b) => a - b, multiply = (a, b) => a * b, calculate = (...args) => args[Math.floor(Math.random() * args.length)]; let result = calculate(add, subtract, multiply)(1, 3); console.log(result); 

This isn't a great example for teaching currying. 这不是教授curry的好例子。 I think what the instructor/course is trying to get across here is that when you do: 我认为讲师/课程试图在这里讲解的是,当您这样做时:

let result = calculate(add, subtract, multiply)(1,3)

you're calling a function ( calculate ) that returns a function (one of the three you pass it, I guess picked at random though the assignment is unclear), and then you're calling that function (by using (1,3) on the result of the calculate(...) call. 您正在调用一个函数( calculate ),该函数返回一个函数(您传递的三个函数之一,尽管分配不清楚,我猜是随机选择的),然后调用该函数(通过使用(1,3)根据calculate(...)调用的结果。

calculate can be a one-liner: calculate可以是单线的:

function calculate(...fns) {
    return fns[Math.floor(Math.random() * fns.length)];
}

or in ES5: 或在ES5中:

function calculate() {
    return arguments[Math.floor(Math.random() * arguments.length)];
}

Live Example: 现场示例:

 function add(num1, num2){ return num1 + num2; } function subtract(num1, num2){ return num1 - num2; } function multiply(num1, num2){ return num1 * num2; } function calculate(...fns) { return fns[Math.floor(Math.random() * fns.length)]; } let result = calculate(add, subtract, multiply)(1,3); console.log(result); 


A more useful example to teach currying would be: 教递归的一个更有用的例子是:

let result = calculate(add, subtract, multiply)(1)(3);
// ----------------------------------------------^^

Notice that we're calling the result of calculate with 1 , then calling the result of that with 3 . 请注意,我们调用的结果calculate1 ,然后调用的 ,结果3 Then, calculate would need to wrap the function it picks in another function that collects the 1 and then waits to be called with the 3 : 然后, calculate需要将它选择的函数包装在另一个收集1函数中,然后等待被3调用:

function calculate(...fns) {
    const fn = fns[Math.floor(Math.random() * fns.length)];
    return (a) => {
        return (b) => {
            return fn(a, b);
        };
    };
}

or more concisely, but less clearly: 或更简洁,但不太清楚:

function calculate(...fns) {
    const fn = fns[Math.floor(Math.random() * fns.length)];
    return (a) => (b) => fn(a, b);
}

Live Example: 现场示例:

 function add(num1, num2){ return num1 + num2; } function subtract(num1, num2){ return num1 - num2; } function multiply(num1, num2){ return num1 * num2; } function calculate(...fns) { const fn = fns[Math.floor(Math.random() * fns.length)]; return (a) => (b) => fn(a, b); } let result = calculate(add, subtract, multiply)(1)(3); console.log(result); 

The function returned by calculate , when called, remembers a and returns a new function; 通过返回的函数calculate ,调用时,记得a并返回一个新的功能; that function, when called, gets b and calls fn(a, b) to get the result. 该函数在被调用时获取b并调用fn(a, b)获得结果。

That example picks the function up-front, but it could pick it at the end as well: 该示例预先选择了函数,但也可以在最后选择它:

function calculate(...fns) {
    return (a) => (b) => fns[Math.floor(Math.random() * fns.length)](a, b);
}

Live Example: 现场示例:

 function add(num1, num2){ return num1 + num2; } function subtract(num1, num2){ return num1 - num2; } function multiply(num1, num2){ return num1 * num2; } function calculate(...fns) { return (a) => (b) => fns[Math.floor(Math.random() * fns.length)](a, b); } let result = calculate(add, subtract, multiply)(1)(3); console.log(result); 

calculate should return one of the functions so the result of the calculate function should be called with the actual params: 计算应返回函数之一,因此应使用实际参数来调用计算函数的结果:

 function add(num1, num2){ return num1 + num2; } function subtract(num1, num2){ return num1 - num2; } function multiply(num1, num2){ return num1 * num2; } function calculate(add, subtract, multiply){ let randNum = Math.floor(Math.random() * 3) + 1 switch(randNum){ case 1: return add break; case 2: return subtract break; case 3: return multiply break; } } console.log(calculate(add, subtract, multiply)(2, 4)); 

You have two problems in this part of the code, inside your calculate function: 在这部分代码中,您在calculate函数内部有两个问题:

  switch(randNum){
    case 1:
      let add = add(num1, num2)
      break;

    case 2:
      let subtract = subtract(num1, num2);
      break;

    case 3:
      let multiply = multiply(num1, num2);
      break;


  1. You're calling you math functions (ej. add(num1, num2) ) inside calculate . 你打电话给你的数学函数(EJ。 add(num1, num2)计算 This will return a number but the expected behaviour is that it will return a function, so that you can call it with further parameters: 这将返回一个数字,但是预期的行为是它将返回一个函数,以便您可以使用更多参数来调用它:

     let result = calculate(add, subtract, multiply)(1,3) 


  2. Your calculate function is not returning any value. 您的calculate函数未返回任何值。 Thus, when your doing let result = calculate(...) , result will always be undefined. 因此,当您执行let result = calculate(...) ,结果将始终是不确定的。


Instead of this, your calculate function should return a function: 取而代之的是,您的calculate函数应返回一个函数:

    function calculate(add, subtract, multiply){

      let randNum = Math.floor(Math.random() * 3) + 1;

      switch(randNum){
          case 1:
          return add;

          case 2:
          return subtract;

          case 3:
          return multiply;
      }
    }

Demo: https://jsbin.com/jiholifife/edit?js,console 演示: https : //jsbin.com/jiholifife/edit?js,console


Note the difference: your function calculate is now returning a function. 注意区别: 函数 calculate 现在返回一个函数。
This is possible due to the fact that functions in JavaScript are First-Class objects: a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable. 这是可能的,因为JavaScript中的函数是First-Class对象:一个函数可以作为参数传递给其他函数,可以由另一个函数返回,并且可以作为值分配给变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM