2015-11-24 29 views
5

Attualmente sto lavorando su un problema di programmazione nel mio tempo personale che richiede di eseguire una funzione javascript che può essere chiamato in questo modoScrivere una funzione javascript al curry che può essere chiamata un numero arbitrario di volte che restituisce un valore sull'ultima chiamata di funzione

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 

Quello che sto avendo problemi a capire è come farlo restituisce un valore sulla molto ultima chiamata.

Ad esempio, affinché add(1)(2) lavorare, poi add(1) deve restituire una funzione, ma secondo le istruzioni add(1) quando chiamato da solo tornerà 1.

Sto assumendo che un modo per superare questo è capire quante volte in successione viene chiamata la funzione add, ma non riesco a pensare a un modo per riuscirci. Qualcuno ha qualche suggerimento che possa indicarmi la giusta direzione?

Ho letto questi due articoli (1, 2) sulla funzione di elaborazione e li capisco, ma non sono sicuro di come fare il currying quando si ha a che fare con un numero variabile di argomenti.

+2

Allora, cosa hai provato? Un sacco di esempi di curriculum in rete. si restituisce la funzione ... – epascarello

+1

@epascarello scusa se non l'ho chiarito. Ho letto questo http://www.crockford.com/javascript/www_svendtofte_com/code/curried_javascript/index.html e questo http://blog.carbonfive.com/2015/01/14/gettin-freaky-functional -wcurried-javascript /. Per quanto riguarda i miei tentativi, sono stati così fuori che non vedo il valore nel pubblicarli. Inoltre non ho problemi con il currying stesso. Ho un problema con la funzione che prende un numero variabile di chiamate prima che si risolva definitivamente. Non so come sistemarlo. – m0meni

+0

Btw, invece di usare le funzioni variadiche, dovresti risolvere i problemi corrispondenti con funzioni di operatore riduttore e binario, o con una funzione "semi-variadica", dove gli argomenti variadici vengono passati come una matrice. Questo si adatta molto meglio allo stile funzionale. Le funzioni variabili creano più problemi di quelli che risolvono e dovrebbero essere evitati. – rand

risposta

2

Non è impossibile, utilizzare 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 quindi questo è un caso in cui '==' ti dà la risposta che vuoi e '===' no. – m0meni

+1

Sì, è ancora impossibile * senza * aggiungere alcune chiamate esterne speciali per interrompere l'invio di argomenti. O per dirlo in modo più chiaro, l'API nella domanda originale è impossibile. – naomik

+1

@naomik È molto meglio che dover terminare il metodo a titolo definitivo o indicare quante iterazioni necessitano il curriculum. Con valueOf tutto ciò che lo chiama internamente otterrà il valore senza che lo sviluppatore debba arrestare manualmente la catena. – epascarello

4

È impossibile eseguire il curry di una funzione variadica con un numero sconosciuto di argomenti.

Dove add è una funzione variadic, si potrebbe fare qualcosa di simile

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

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

Semplicemente non c'è alcun evitare questo tho perché una funzione curry continuerà a restituire una funzione fino a quando viene ricevuto l'ultimo argomento, a quel punto il il calcolo è eseguito.


L'unica altra opzione è quella di creare un modo per "corto circuito" gli argomenti e notificare la funzione che gli argomenti sono fatto di essere inviato. Ciò richiederebbe qualcosa come

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

Qui, il undefined segnala la fine degli argomenti variadic. Non consiglio davvero questo, a causa degli altri problemi che può creare per te. Per non parlare, non è particolarmente bello da guardare.

+0

Stavo pensando la stessa cosa, ma volevo rimanere fiducioso che fosse dovuto alla mia mancanza di conoscenza. Aspetterò e vedrò se qualcuno ha la soluzione miracolosa, ma altrimenti accetterò semplicemente il tuo. – m0meni

+1

@ AR7 Ho fatto [un'altra risposta sulle funzioni di ricerca] (http://stackoverflow.com/a/30249365/633183) che puoi leggere, se sei interessato. – naomik

+0

Sembra che tu non abbia influito sulla stranezza di javascript nella tua risposta. L'Epascarello ce l'ha. – m0meni