Что происходит в этом коде? Я не понимаю, как это работает, не мог бы кто-нибудь, пожалуйста, пройти меня через это

#javascript #recursion #functional-programming #currying

#javascript #рекурсия #функциональное программирование #каррирование

Вопрос:

Может кто-нибудь, пожалуйста, объяснил шаги, которые происходят в этом коде, особенно в отмеченной части. Это рекурсивно, как это объединяется ..?

 const func = x => k => func (k (x))
//                     ^^^^^^^^^^^^      
const add = x => y =>
  x   y

func(1)(add(2))(add(2))(console.log); 

Комментарии:

1. Больше похоже на любопытство к кодированию или уменьшенный / искаженный код. В любом случае, это очень трудно понять, никто никогда не будет писать такие вещи

2. @JeremyThille это довольно стандартный функциональный код. Вряд ли это что-то такое, о чем никто не стал бы писать, или даже что-то из ряда вон выходящее.

3. Ну, в любом случае, я не думаю, что когда-нибудь напишу что-то такое извращенное

4. Это приложение с рекурсивной функцией, от которого вы не можете убежать. Основным шаблоном приложения являются func(1) (inc) (log); журналы 2, func(1) (inc) (inc) (log) журналы 3 и т.д. Базовая структура, которая строится, выглядит так inc(inc(...(1))) .

Ответ №1:

В нынешнем func виде не проверяет тип, потому что мы не можем создать бесконечный тип t a ~ (a -> b) -> t b . Однако мы можем обойти это ограничение, создав новый тип данных следующим образом.

 // Chain :: (forall b. (a -> b) -> Chain b) -> Chain a
const Chain = chain => ({ chain });

// func :: a -> Chain a
const func = x => Chain(k => func(k(x)));

// add :: Number -> Number -> Number
const add = x => y => x   y;

// trace :: a -> a
const trace = x => {
    console.log(x);
    return x;
};

// Chain Number
func(1).chain(add(2)).chain(add(2)).chain(trace); 

Итак, Chain это очень странный тип данных. Это бесконечная цепочка функций, выровненных по типу.

    Chain a
 = (a -> b) -> Chain b
 = (a -> b) -> (b -> c) -> Chain c
 = (a -> b) -> (b -> c) -> (c -> d) -> Chain d
 -- ad infinitum
 

Однако этот тип данных не очень полезен для чисто функционального программирования, потому что вы никогда не сможете использовать Chain значение. Единственный способ, которым вы можете использовать промежуточные результаты в цепочке, — это использовать нечистую функцию, например trace . Я бы посоветовал вам вообще избегать таких бесполезных типов данных.