На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ElcnU, ANDLL, fatalist
  
> curry vs partial , Тупняк
    Доброго времени суток!
    Скажите в чем разница между функциями curry и partial? Не понимаю что может partial чего не может curry и наоборот. Например есть код он выполняет одно и тоже:
    ExpandedWrap disabled
      const foo = (a, b, c) => a + b + c;
      const foo1 = R.partial(foo, [10, 10]);
      const foo2 = R.curry(foo)(10, 10);
       
      console.log(foo1(5)); // 25
      console.log(foo2(5)); // 25

    Тупняк :wall:
        Цитата Астарот @

        это все я давно читал перечитал, но ответа на мой вопрос там нет.

        Короче сам все порешал :D
        вот пример в котором четко все я расписал:
        ExpandedWrap disabled
          const logger = (type, message) => console.log(`[${Date(Date.now())}] [${type}] - ${message}`);
          const debugLog = _.partial(logger, 'Debug');
          const errorLog = _.partial(logger, 'Error');
          const trace = _.curry((title, message) => debugLog(`${title}: ${message}`));
           
          const calc = R.compose(
              R.tap(trace('Mult')),    
              R.multiply(2),    
              R.tap(trace('Sum')),  
              R.sum,  
          );
           
          calc([1,2,3,4,5]);
          // [Mon Aug 05 2019 22:32:28 GMT-0700 (GMT-07:00)] [Debug] - Sum: 15
          // [Mon Aug 05 2019 22:32:28 GMT-0700 (GMT-07:00)] [Debug] - Mult: 30
        Сообщение отредактировано: Cfon -
          По сути в чисто функциональном языке, таком как Хаскель, все функции каррированы автоматом, поэтому в нем нет никаких вспомогательных функций типо curry и partial. В JS также все можно написать без partial:
          ExpandedWrap disabled
            // каррируем
            const logger = _.curry((type, message) =>
                console.log(`[${Date(Date.now())}] [${type}] - ${message}`));  
            // частично применяем
            const debugLog = logger('Debug');

          Спросите зачем тогда partial в JS? :huh:
          Как оказалось все просто :D
          Поскольку в JS функции не каррированы, если нам нужно частично применить их, то мы можем заюзать partial, без предварительного каррирования, как в примере с debugLog:
          ExpandedWrap disabled
            // non-curried function
            const logger = (type, message) => console.log(`[${Date(Date.now())}] [${type}] - ${message}`);
            // partially applied function
            const debugLog = _.partial(logger, 'Debug');

          А если нам надо в последствии частично применять функцию, как например, в случае передачи функции trace в compose из примера выше, мы предварительно каррируем функцию и потом вызываем ее с необходимыми параметрами, т.е. частично применяем.

          Хотя нам никто не мешает заюзать partial и тут без каррирования :D
          ExpandedWrap disabled
            // не карированная функция
            const trace = (title, message) => debugLog(`${title}: ${message}`);
            // частично применяем через partial
            const calc = R.compose(
                R.tap(_.partial(trace, 'Mult')),
                R.multiply(2),  
                R.tap(_.partial(trace, 'Sum')),
                R.sum,  
            );

          Но это ИМХО моветон.

          Важно понимать, что результатом частичного применения функции является новая функция. Но если каррированной функции передать все параметры, т.е. выполнить полное применение, то результатом будет какое то значение.

          Ставте лайки если поняли :lool:
          Я вскрыл суть curry и partial, до меня никто этого не делал :D
          Сообщение отредактировано: Cfon -
            Еще один пример того, где лучше заходит _.partial, а не _.curry, это функции с параметром ...args, например setTimeout. Каррировать такие функции можно, но они превращаются в функции с фиксированным числом параметров, т.е отбрасываем ...args. След код работает
            ExpandedWrap disabled
              const delay = _.curry(setTimeout, 2)
              const delay2 = delay(_, 2000)
              delay2(() => console.log('Done.'))

            а след вызов работает, но он не видит передаваемые в колбэк аргументы
            ExpandedWrap disabled
              delay2(a => console.log(a + ' Done.'), 'OK.')

            Через _.partial в обоих случаях все пучком
            ExpandedWrap disabled
              const delay2 = _.partial(setTimeout, _, 2000)
              delay2(() => console.log('Done.'))
              delay2(a => console.log(a + ' Done.'), 'OK.')


            Пардон ошибочка! :jokingly: В случае с _.curry тоже работает! :D
            С одной поправкой в _.curry надо указать число аргументов для каррирования, иначе получится функция, которую нельзя будет полностью применить :D

            - Маста, а что значит применить функцию? :huh:

            Говоря по простому вызвать :D
            Этот термин идет из чисто функциональных языков, где функции не вызываются, а применяются к аргументам. Если у функции несколько параметров и она применяется к одному из них, то говорят что она частично применена. А если ее применить ко всем параметрам, то это называется полное применение. Я уже приводил эти магические фразы :D
            Результат частичного применения всегда новая функция, которая включает функциональность исходной функции, а вот полное применение возвращается конечное значение (число, строка, объект).
            Сообщение отредактировано: Cfon -
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0238 ]   [ 15 queries used ]   [ Generated: 18.04.24, 14:24 GMT ]