#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
. Я бы посоветовал вам вообще избегать таких бесполезных типов данных.