NodeJS вывод - функция вместо напечатанных строк - PullRequest
0 голосов
/ 11 марта 2020

У меня проблемы с печатью правильного результата в NodeJS, почему мой код не печатает строки правильным образом? Я чувствую, что console.log не вызывается вообще. Почему я получаю:

[Function]
[Function]
[Function]
[Function]

Ожидаемый результат:

Tigrou (buddy of Spider) was here!
Spider (buddy of Tigrou) was also here!
Tigrou (buddy of Spider) are in a boat...
1 (buddy of 2)3

Код, который я думал, будет работать:

function build_sentence(...args)
{
    var i = 0
    var s = ""
    for (let arg of args)
    {
        if (i == 1)
        {
            i++
            s += "(buddy of " + arg + ") "
        }
        else
        {
            s += arg + " "
            i++
        }
    }
    return s
}

function mycurry(build_sentence)
{
    return function(...args)
    {
        if (!args)
        {
            return build_sentence();
        }
        else
        {
            return mycurry(build_sentence.bind(this, ...args))
        }
    }
}

const curried = mycurry(build_sentence);
console.log(curried("Tigrou")("Spider")(" was here!"))
console.log(curried("Spider")("Tigrou")(" was also here!"))
console.log(curried("Tigrou", "Spider", " are in a boat... "))
console.log(curried(1)(2, 3))

Ответы [ 3 ]

0 голосов
/ 11 марта 2020

основная проблема в нашем коде заключается в том, что !args всегда ложно, так как [] для логического значения также true.

вы должны использовать !args.length. однако вам следует добавить дополнительный вызов к использованию вашей функции карри, например curried(1)(2, 3)().

другой подход использует сравнение числа требуемых параметров в карри-функции (build_sentence.length) и количества переданных параметров (args.length), но он не работает со сценарием распространения.

upd:

ex.1 - использование свойства Function.prototype.length

const curry = fn => 
  (...args) => 
    fn.length <= args.length 
      ? fn(...args) 
      : curry(fn.bind(this, ...args));

const func1 = (a, b, c) => `${a},${b},${c}`;
const func2 = (...args) => args.join(',');

console.log(curry(func1)(1,3)(4));
console.log(curry(func1)(1,3,4));
console.log(curry(func1)(1)(3)(4));

console.log(curry(func2)(1));

в этом случае карри будет работать нормально для func1 (функция, имеющая перечисляемое количество аргументов), потому что func1.length = 3. однако для func2 - func2.length = 0, поэтому (curry(func1)) будет выполнено после первого вызова.

ex.2 - с использованием числа переданных аргументов

const curry = fn => 
  (...args) => 
    !args.length 
      ? fn() 
      : curry(fn.bind(this, ...args));
      
const func = (...args) => args.join(',');

console.log(curry(func)(1)(2,3,4)(5)());

в этом случае функция curry будет возвращать только результат выполнения fn при вызове без аргументов. однако он будет правильно обрабатывать неисчислимые аргументы функции карри.

0 голосов
/ 12 марта 2020

Вот вам полное рабочее решение (кроме интервала строк)

const build_sentence_n_params = 3;

function build_sentence(...args)
{
    var i = 0
    var s = ""
    for (let arg of args)
    {
        if (i == 1)
        {
            i++
            s += "(buddy of " + arg + ") "
        }
        else
        {
            s += arg + " "
            i++
        }
    }
    return s
}

// A generic n-parameter curry helper, that returns fn return value
// after n-parameters given, and continues currying with more parameters.
// Note that in this configuration, the caller would also need
// to know how many parameters to give before a value is returned.
function ncurry(fn, n)
{
    // Note that we have to return an outer function here, rather than just
    // returning `curry` function directly, so `params` is unique for each
    // initial call to `curried`.
    return function(...args) {    
        // Initial arguments (note: we can use this array without copy, since
        // rest params will always be a new array)
        const params = args;
        // This function contains the return logic without having to duplicate it below
        function next() {
            // If we have all params, call the given function, otherwise
            // return the curry function again for more parameters
          return !n || params.length >= n ? fn.call(null, ...params) : curry;
        }
        // The outer function is only called once, but this curry
        // function will be called for each additional time.
        function curry(...args) {
            // Accumulate additional arguments
            params.push(...args)
            return next();
        };
        return next();
    };
}

function mycurry(build_sentence)
{
    // Call the generic n-parameter curry helper to generate
    // a specific curry function for our purposes.
    return ncurry(build_sentence, build_sentence_n_params);
}

const curried = mycurry(build_sentence);
console.log(curried("Tigrou")("Spider")(" was here!"))
console.log(curried("Spider")("Tigrou")(" was also here!"))
console.log(curried("Tigrou", "Spider", " are in a boat... "))
console.log(curried(1)(2, 3))
0 голосов
/ 11 марта 2020

Ваш вызов методов довольно запутанный, поэтому я позволил себе упростить ваш код.

Если вы выполните следующее:

 const curried = build_sentence("Tigrou", "Spider", " was here!");
 console.log(curried);

Вы получите желаемый результат:

Тигроу (приятель Паука) был здесь!

Почему вы используете метод mycurry, я не понимаю.

При отладке вашего кода предложение уже построено на первом вызове, и что происходит в том случае, если последующие вызовы на самом деле не являются вызовами внутренних функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...