2015-11-24 41 views
5

Obecnie pracuję nad problemem programowania w moim osobistym czasie, który prosi o utworzenie funkcji javascript, która może nazywać się w ten sposób.Pisanie funkcji curried javascript, którą można nazwać dowolną liczbę razy, która zwraca wartość na ostatnim wywołaniu funkcji

add(1) // 1 
add(1)(2) // 3 
add(1)(2)(3); // 6 
add(1)(2)(3)(4); // 10 
add(1)(2)(3)(4)(5); // 15 

Mam problem z wymyśleniem, jak sprawić, by zwracał wartość przy ostatnim połączeniu.

Na przykład, w celu add(1)(2) do pracy, to add(1) musi powrócić do funkcji, jednak zgodnie z instrukcjami add(1) gdy wywołana przez sam wróci 1.

Zakładam, że jednym ze sposobów rozwiązania tego problemu jest ustalenie, ile razy z rzędu jest wywoływana funkcja add, ale nie mogę wymyślić, jak to osiągnąć. Czy ktoś ma jakieś wskazówki, które mogą wskazać mi właściwy kierunek?

Czytałem te dwa artykuły (1, 2) o funkcji curry i rozumiem je, ale nie jestem pewien, jak zrobić curry, gdy mamy do czynienia ze zmienną liczbą argumentów.

+2

Więc co pan spróbować? Mnóstwo przykładów curry w sieci. zwrócisz funkcję ... – epascarello

+1

@epascarello Przepraszam, jeśli nie wyjaśniłem. Przeczytałem ten http://www.crockford.com/javascript/www_svendtofte_com/code/curried_javascript/index.html i ten http://blog.carbonfive.com/2015/01/14/gettin-freaky-functional -wcurried-javascript /. Jeśli chodzi o moje próby, to tak się stało, że nie widzę wartości w ich publikowaniu. Nie mam też problemu z samostanowaniem. Mam problem z funkcją przyjmującą zmienną liczbę wywołań, zanim ostatecznie się rozwiąże. Nie wiem, jak to pomieścić. – m0meni

+0

Btw, zamiast używać funkcji variadic, powinieneś rozwiązać odpowiednie problemy albo przy pomocy funkcji redukcji i binarnych operatorów, albo z funkcją "semi-variadic", w której argumenty variadic są przekazywane jako tablica. To znacznie lepiej pasuje do stylu funkcjonalnego. Funkcje Variadic stwarzają więcej problemów niż rozwiązują i należy ich unikać. – rand

Odpowiedz

2

Nie jest to niemożliwe, użyj valueOf().

function add(initNum) { 
 
    var sum = initNum; 
 
    var callback = function (num) { 
 
     sum += num; 
 
     return callback; 
 
    }; 
 
    callback.valueOf = function() { 
 
     return sum; 
 
    }; 
 
    return callback; 
 
}; 
 
console.log(add(1)(2)==3);   //true 
 
console.log(add(1)(1)+1);    //3 
 
console.log(add(1)(2)(3).valueOf()); //6

+0

Ah, więc to jest jeden przypadek, w którym '==' daje odpowiedź, której potrzebujesz, a '===' nie. – m0meni

+1

Tak, nadal jest to niemożliwe * bez * dodawania specjalnego zewnętrznego połączenia w celu zakończenia wysyłania argumentów. Lub, aby powiedzieć to wyraźniej, API w pierwotnym pytaniu jest niemożliwe. – naomik

+1

@naomik Jest to o wiele lepsze rozwiązanie niż konieczność natychmiastowego zakończenia metody lub podanie liczby powtórzeń, których potrzebuje currying. Dzięki valueOf wszystko, co wywołuje to wewnętrznie, otrzyma wartość bez konieczności ręcznego zatrzymywania łańcucha przez programistę. – epascarello

4

Niemożliwe jest curry funkcji variadic z nieznaną liczbą argumentów.

Gdzie add jest o zmiennej liczbie argumentów funkcji, można zrobić coś jak

var add5 = curryN(add, 5); 
add5(1)(2)(3)(4)(5); //=> 15 

var add3 = curryN(add, 3); 
add3(1)(2)(3); //=> 6 

Po prostu nie ma unikanie tego tho bo curry funkcja będzie nadal zwracać funkcję do momentu otrzymania ostatni argument, w którym to punkcie obliczenia są uruchamiane.


Jedyną opcją jest stworzenie sposobu na "zwarcie" argumentów i powiadomienie funkcji, że wysyłane są argumenty. Wymagałoby to coś podobnego

var xadd = curryUntilUndefined(add); 
xadd(1)(2)(3)(4)(5)(undefined); //=> 15 

Tutaj undefined sygnalizuje koniec o zmiennej liczbie argumentów argumentów. Naprawdę nie polecam tego z powodu innych problemów, które może on stworzyć dla ciebie. Nie wspominając, że nie jest szczególnie miło na to patrzeć.

+0

Myślałem o tym samym, ale chciałem mieć nadzieję, że wynika to z mojego braku wiedzy. Zamierzam poczekać i zobaczyć, czy ktoś ma cudowne rozwiązanie, ale w przeciwnym razie po prostu zaakceptuję twoje. – m0meni

+1

@ AR7 Zrobiłem [kolejną odpowiedź na temat funkcji curry] (http://stackoverflow.com/a/30249365/633183) możesz przeczytać, jeśli jesteś zainteresowany. – naomik

+0

Wygląda na to, że nie przyczyniłeś się do dziwactwa javascript w twojej odpowiedzi. Epascarello to dostał. – m0meni