2016-07-19 9 views
0

Учитывая это рекуррентное map функция:Может ли рекурсивная функция в карри форме быть хвостом рекурсивным?

const U = f => f(f); 
 
    
 
const map = f => U(h => acc => ([head, ...tail]) => head === undefined 
 
? acc 
 
: h(h)([...acc, f(head)])(tail))([]); 
 
    
 
const xs = [1,2,3,4,5]; 
 
console.log(map(x => x * x)([1,2,3,4,5]));

Очевидно, что рекурсивный вызов h(h) не последнее действие рекурсивной функции. Но когда стек размотан, все, что происходит, - это то, что готовый аккумулятор возвращается без каких-либо дальнейших изменений или операций. Is map против моих ожиданий хвост рекурсивный?

+0

Я думаю, что это запутанная 'реализация map'. Он смешивает 'map' и' reduce' вместе в одной процедуре. Я делюсь [gist: u.js, y.js] (https://gist.github.com/anonymous/6ccdd17b0b16f75bc38af2930ca6655f), чтобы показать, что две отдельные процедуры помогают прочитать «карту». Я также выполнил реализацию с использованием 'Y', чтобы показать, как сравниваются две реализации. Вы, наверное, знаете это, но единственная разница с 'Y' заключается в том, что вы просто применяете' h' вместо 'h (h)'. О, да, хвост звонит повсюду. Теперь мы просто ждем на двигателе, который реализует устранение хвостового вызова ... – naomik

+0

Спасибо @naomik, я абсолютно согласен с вами. Это была просто проблема, как «карта» может быть реализована без получения ее из «уменьшения». У меня не было намерения публиковать это, до тех пор, пока явное приложение в хвосте не сбило меня с толку. – ftor

+0

Нет проблем **^_^** – naomik

ответ

2

рекурсивный вызов h(h) не последнее действие рекурсивной функции

h(h) не рекурсивный вызов. …(tail) - это рекурсивный вызов, и да, он находится в положении хвоста.

Это может получить более очевидным, если вы уронили что усложненный U комбинатор (или по крайней мере использовал Y комбинатора сразу):

const map = f => { 
    const mapF = acc => ([head, ...tail]) => head === undefined 
    ? acc 
    : mapF([...acc, f(head)])(tail); 
    return mapF([]); 
}; 
+0

Спасибо, но 'U' предотвращает повторную передачу' f' ('h') и что требуется блок. Btw, каково название таких стрелок с '{}'? – ftor

+0

Как я уже говорил, вы можете использовать 'Y', чтобы делать то, что делает объявление' mapF', если вы заботитесь. Но это не имеет большого значения, я использовал этот синтаксис только для некоторой ясности, ваш исходный код так же рекурсивный. Стрелки без кратким телом все еще остаются функциями стрелок. – Bergi

+0

О, черт возьми, рекурсивный вызов выполняется при завершении процедурного применения функции curried. Я такой я ... я этого не видел! – ftor

 Смежные вопросы

  • Нет связанных вопросов^_^