写一个计算器函数——最函数式的编程方式(javascript)

Writing a calculator function - in the most functional programming way(javascript)

我正在尝试 codewars 中的一项任务,并希望在 javascript 中以函数式编程方式编写。我对我的功能以及如何以更好的方式编写代码有一些疑问。

任务本身就是构建一个计算器函数。它将接受以下格式的输入:

'..... + ...'

计算器必须将字符串拆分为表示运算的中间字符,然后剩下的两个字符串就是两个值。在上面的示例中,第一个值为 5,第二个值为 3。完成后,根据运算符执行操作 - 加法、乘法等。

这是我的代码:

function dotCalculator(equation) {

    function returnSymbol(input) {

        if (input.includes(' + ')) {
            return ' + ';
        } else if (input.includes(' - ')) {
            return ' - ';
        } else if (input.includes(' * ')) {
            return ' * ';
        } else if (input.includes(' / ')) {
            return ' / ';
        }

    }

    let symbolOf = returnSymbol;

    let result = equation.split(symbolOf(equation)).map(x => x.length);
    
    // Array.prototype.add = function(){
    //     return this[0] + this[1];
    // }
}

我知道我的代码还没有完成。我试图了解如何以函数式编程的思维方式正确完成它。也许原型继承会有点矫枉过正。我正在寻找任何愿意伸出援手的人的一些想法。我尝试在

之后写一个更复杂的 reduce
let arrMine = equation.split(symbolOf(equation)).map((x) => x.length);

但看起来太乱了。任何帮助将不胜感激。

此示例中的函数程序可以计算简单的算术运算——两个数字的加、减、乘或除。

详情见下方示例
注意: 在任何传递给 calc() 的负数前加上下划线 _ 而不是连字符 -

// Utility function
const log = data => console.log(JSON.stringify(data));

// Arithmetic functions
const sum = (a, b) => (+a) + (+b);
const dif = (a, b) => a - b;
const pro = (a, b) => a * b;
const quo = (a, b) => a / b;

/**
 * Calculate a simple formula a+b, a-b, a*b, or a/b.
 * @param {string} formula - Pattern:
 *  "numberOPERANDnumber" ex. "5+5"
 *  Use an underscore to prefix negative numbers.
 * @returns {number} Result of formula
 */
const calc = formula => {
  // Declare variables
  let result, f, a, b, op;

  /*
  Convert string into an array of strings.
  [number, operand, number]
  Replace any _ with - (see @param)
  */
  f = formula.split(/([+\-*/])/)
    .map(ab => ab.replace('_', '-'));

  /*
  Convert string of numbers into real numbers.
  */
  a = parseFloat(f[0]);
  b = parseFloat(f[2]);
  op = f[1];

  /*
  Check if >a< and >b< are real numbers and if the input string was split 
  into 3 strings.
  */
  if (Number.isNaN(a) || Number.isNaN(b) || f.length != 3) {
    return;
  }

  // >op< determines the method of resolving the formula
  switch (op) {
    case '+':
      result = sum(a, b);
      break;
    case '-':
      result = dif(a, b);
      break;
    case '*':
      result = pro(a, b);
      break;
    case '/':
      result = quo(a, b);
      break;
    default:
      return;
  }
  return result;
};

log(calc('5+5'));
log(calc('_10-7')); // That's a -10 (see @param)
log(calc('5*9'));
log(calc('51/3'));

我是一个非常函数式编程的新手,这里的管道函数可能有点无用,我可能过于字面地理解了 ..... + ... 示例,但这是一个尝试:

const arith = {
  '+': (a, b) => a + b,
  '-': (a, b) => a - b,
  '*': (a, b) => a * b,
  '/': (a, b) => a / b,
};

const pipe = (...fns) => (arg) => fns.reduce((res, fn) => fn(res), arg);

const get_input_elements = (input) => input.split(' ');

const get_number = (dots) => dots.length;

const get_numbers = ([str_a, op, str_b]) =>
  [get_number(str_a), op, get_number(str_b)];

const apply_arith = ([a, op, b]) => arith[op](a, b);

const calc = pipe(
  get_input_elements,
  get_numbers,
  apply_arith
);

console.log(calc('..... + ...'));
console.log(calc('..... - ...'));
console.log(calc('...... / ..'));