it-swarm-eu.dev

JavaScript curry: jaké jsou praktické aplikace?

Nemyslím si, že jsem ještě grokkovala kari. Chápu, co to dělá a jak to udělat. Nemůžu si představit situaci, kterou bych použil.

Kde používáte curicing v JavaScriptu (nebo kde jsou hlavní knihovny používány)? DOM manipulace nebo obecné příklady vývoje aplikací vítány.

Jedna z odpovědí zmiňuje animaci. Funkce jako slideUp, fadeIn berou prvek jako argumenty a jsou obvykle curriedovou funkcí, která vrací funkci vysokého řádu s výchozí vestavěnou funkcí „animace“. Proč je to lepší, než pouţití funkce vyšší úrovně s některými výchozími hodnotami?

Existují nějaké nevýhody pro jeho použití?

Zde jsou uvedeny některé dobré zdroje pro zpracování jazyka JavaScript:

V komentářích přidám další položky.


Takže podle odpovědí jsou kurikulární a částečná aplikace obecně vhodnými technikami.

Pokud často „vylepšujete“ funkci na vysoké úrovni tak, že ji voláte se stejnou konfigurací, můžete kari (nebo použít částečnou Resig) funkci vyšší úrovně pro vytvoření jednoduchých, stručných pomocných metod.

166
Dave Nolan

@Hank Gay

V reakci na komentář EmbiggensTheMind:

Nemohu přemýšlet o instanci, kde currying - sám o sobě je užitečný v JavaScriptu; je to technika pro převod volání funkcí s více argumenty do řetězců volání funkcí s jedním argumentem pro každé volání, ale JavaScript podporuje více argumentů při volání jedné funkce. 

V JavaScriptu - a předpokládám, že většina dalších skutečných jazyků (ne lambda kalkulu) - je běžně spojena s částečnou aplikací, ačkoli. John Resig vysvětluje to lépe , ale Gist je to, že má nějakou logiku, která bude aplikována na dva nebo více argumentů, a vy znáte pouze hodnoty pro některé z těchto argumentů. 

Částečnou aplikaci/currying můžete použít k opravě těchto známých hodnot a k návratu funkce, která přijímá pouze neznámé hodnoty, které mají být vyvolány později, když skutečně máte hodnoty, které chcete předat. To poskytuje šikovný způsob, jak se vyhnout opakování, když byste byli volání stejné vestavěné JavaScript znovu a znovu se všemi stejnými hodnotami, ale jedna. Ukrást Johnův příklad:

String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );
31
Hank Gay

Zde je zajímavé a praktické využití curicing v JavaScriptu, který používá uzávěry :

function converter(toUnit, factor, offset, input) {
    offset = offset || 0;
    return [((offset + input) * factor).toFixed(2), toUnit].join(" ");
}

var milesToKm = converter.curry('km', 1.60936, undefined);
var poundsToKg = converter.curry('kg', 0.45460, undefined);
var farenheitToCelsius = converter.curry('degrees C', 0.5556, -32);

milesToKm(10);            // returns "16.09 km"
poundsToKg(2.5);          // returns "1.14 kg"
farenheitToCelsius(98);   // returns "36.67 degrees C"

To závisí na curry rozšíření Function, ačkoli jak vidíte, používá se pouze apply (nic příliš fantázního):

Function.prototype.curry = function() {
    if (arguments.length < 1) {
        return this; //nothing to curry with - return function
    }
    var __method = this;
    var args = toArray(arguments);
    return function() {
        return __method.apply(this, args.concat([].slice.apply(null, arguments)));
    }
}
110
Prisoner ZERO

V JavaScriptu jsem nalezl funkce, které se podobají pythonskému functools.partial:

function partial(fn) {
  return partialWithScope.apply(this,
    Array.prototype.concat.apply([fn, this],
      Array.prototype.slice.call(arguments, 1)));
}

function partialWithScope(fn, scope) {
  var args = Array.prototype.slice.call(arguments, 2);
  return function() {
    return fn.apply(scope, Array.prototype.concat.apply(args, arguments));
  };
}

Proč byste ji chtěli použít? Běžnou situací, kdy chcete tuto funkci použít, je to, když chcete this v rámci funkce vázat na hodnotu:

var callback = partialWithScope(Object.function, obj);

Když se nazývá zpětné volání, this ukazuje na obj. To je užitečné v situacích událostí nebo pro úsporu místa, protože obvykle dělá kód kratší.

Currying je podobná částečnému s tím rozdílem, že funkce, kterou má currying vrací, přijímá pouze jeden argument (pokud tomu rozumím).

6
Armin Ronacher

Souhlasit s Hank Gayem - Je to velmi užitečné v jistých funkčních programovacích jazycích - protože je to nezbytná součást. Například, v Haskellu jednoduše nemůžete vzít více parametrů do funkce - nemůžete to udělat v čistě funkčním programování. Vezměte si jeden param najednou a budujte svou funkci. V JavaScriptu je to prostě zbytečné, navzdory vymysleným příkladům, jako je „konvertor“. Zde je stejný kód převodníku, aniž by bylo nutné provádět:

var converter = function(ratio, symbol, input) {
    return (input*ratio).toFixed(2) + " " + symbol;
}

var kilosToPoundsRatio = 2.2;
var litersToUKPintsRatio = 1.75;
var litersToUSPintsRatio = 1.98;
var milesToKilometersRatio = 1.62;

converter(kilosToPoundsRatio, "lbs", 4); //8.80 lbs
converter(litersToUKPintsRatio, "imperial pints", 2.4); //4.20 imperial pints
converter(litersToUSPintsRatio, "US pints", 2.4); //4.75 US pints
converter(milesToKilometersRatio, "km", 34); //55.08 km

Doufám, že Douglase Crockforda v "JavaScriptu: Dobré části", jsem si přál, aby se zmínil o historii a skutečném použití kurýře, spíše než o jeho offhanded poznámkách. Po nejdelším čase po přečtení jsem byl zmatený, až jsem studoval funkční programování a uvědomil si, odkud pochází.

Po nějaké další přemýšlení, já předpokládám, že je jeden platný případ použití pro currying v JavaScriptu: pokud se snažíte psát pomocí čistě funkčních programovacích technik pomocí JavaScriptu. Vypadá to však jako případ vzácného použití.

5
Byron Katz

Zde je příklad.

Jsem instrumentace spoustu polí s JQuery, takže vidím, co uživatelé mají. Kód vypadá takto:

$('#foo').focus(trackActivity);
$('#foo').blur(trackActivity);
$('#bar').focus(trackActivity);
$('#bar').blur(trackActivity);

(Pro uživatele, kteří nejsou členy JQuery, říkám, že kdykoliv se několik políček dostane nebo ztratí zaostření, chci, aby byla funkce trackActivity () volána. Mohla bych také použít anonymní funkci, ale musela bych ji duplikovat 4 krát, tak jsem ho vytáhl a pojmenoval.)

Nyní se ukazuje, že jedna z těchto oblastí musí být řešena odlišně. Chtěl bych být schopen předat parametr v jednom z těchto hovorů, které budou předány naší infrastruktuře sledování. S kari, můžu.

2
William Pietri

Není to žádné kouzlo nebo něco ... jen příjemná zkratka pro anonymní funkce.

partial(alert, "FOO!") je ekvivalentní function(){alert("FOO!");}

partial(Math.max, 0) odpovídá function(x){return Math.max(0, x);}

Volání na částečné ( MochiKit terminologie. Myslím, že některé další knihovny poskytují funkce .curry metody, která dělá to samé) vypadají o něco hezčí a méně hlučné než anonymní funkce.

2
Marijn

Funkce JavaScriptu se nazývají lamda v jiném funkčním jazyce. Může být použit k vytvoření nového api (výkonnější nebo komplexnější funkce) na základě jednoduchého vstupu jiného vývojáře. Curry je jen jedna z technik. Můžete jej použít k vytvoření zjednodušeného api pro volání komplexního api. Pokud jste develper, který používá zjednodušený api (například používáte jQuery pro jednoduchou manipulaci), nemusíte používat kari. Ale pokud chcete vytvořit zjednodušený api, kari je váš přítel. Musíte napsat rámec javascriptu (jako jQuery, mootools) nebo knihovnu, pak můžete ocenit jeho moc. Napsal jsem vylepšenou kari funkci, na http://blog.semanticsworks.com/2011/03/enhanced-curry-method.html . Nepotřebujete kari metodu dělat currying, je to jen pomoci dělat currying, ale můžete to udělat vždy ručně napsáním funkce A () {} vrátit další funkci B () {}. Chcete-li učinit zajímavější, použijte funkci B() pro návrat další funkce C ().

1
Fred Yang

Znám jeho staré vlákno, ale musím ukázat, jak se to používá v knihovnách JavaScriptu:

Budu používat knihovnu lodash.js konkrétně k popisu těchto pojmů.

Příklad:

var fn = function(a,b,c){ 
return a+b+c+(this.greet || ‘'); 
}

Částečná aplikace:

var partialFnA = _.partial(fn, 1,3);

Currying: 

var curriedFn = _.curry(fn);

Vazba: 

var boundFn = _.bind(fn,object,1,3 );//object= {greet: ’!'}

používání:

curriedFn(1)(3)(5); // gives 9 
or 
curriedFn(1,3)(5); // gives 9 
or 
curriedFn(1)(_,3)(2); //gives 9


partialFnA(5); //gives 9

boundFn(5); //gives 9!

rozdíl:

po currying dostaneme novou funkci bez parametrů předem vázaných.

po částečné aplikaci dostaneme funkci, která je vázána na některé parametry prebound.

ve vazbě můžeme svázat kontext, který bude použit k nahrazení „tohoto“, pokud není vázán výchozí hodnotou jakékoli funkce, bude rozsah okna.

Doporučujeme: Není třeba znovu objevovat kolo. Částečná aplikace/vazba/currying jsou velmi příbuzné. Můžete vidět rozdíl výše. Použijte tento význam kdekoli a lidé rozpoznat, co děláte bez problémů v porozumění a budete muset použít méně kódu.

1
Shishir Arora

Pokud jde o knihovny, které ji používají, vždy je zde Functional .

Kdy je to užitečné v JS? Pravděpodobně ve stejnou dobu je užitečná i v jiných moderních jazycích, ale jediná doba, kdy se mohu vidět, je ve spojení s částečnou aplikací.

1
Hank Gay

Řekl bych, že s největší pravděpodobností všechny animační knihovny v JS používají kari. Namísto toho, aby bylo nutné pro každé volání předávat sadu impaktovaných prvků a funkci, popisující, jak by se měl prvek chovat, funkci vyššího řádu, která zajistí všechny věci načasování, což je pro zákazníka obecně jednodušší uvolnit jako veřejné rozhraní API. funkce jako "slideUp", "fadeIn", která trvá pouze prvky jako argumenty, a to jsou jen některé curried funkce vrací funkci vysokého řádu s výchozí "animace funkce" vestavěné.

1
gizmo

Jen jsem chtěl přidat nějaké zdroje pro Functional.js:

Přednáška/konference vysvětlující některé aplikace http://www.youtube.com/watch?v=HAcN3JyQoyY

Aktualizovaná knihovna Functional.js: https://github.com/loop-recur/FunctionalJS Někteří pěkní pomocníci (omlouvám se tady, žádné pověsti: p): /loop-recur/PreludeJS

Nedávno jsem tuto knihovnu používal, abych snížil opakování v pomocných knihovnách klientů klienta js IRC. Je to skvělá věc - opravdu pomáhá vyčistit a zjednodušit kód. 

Kromě toho, pokud se výkon stane problémem (ale tento lib je docela lehký), je snadné přepsat pomocí nativní funkce.

0
megawac

Pro rychlé a jednořádkové řešení můžete použít nativní vazbu

function clampAngle(min, max, angle) {
    var result, delta;
    delta = max - min;
    result = (angle - min) % delta;
    if (result < 0) {
        result += delta;
    }
    return min + result;
};

var clamp0To360 = clampAngle.bind(null, 0, 360);

console.log(clamp0To360(405)) // 45

0
cstuncsik

Právě jsem napsal příklad jPaq, který ukazuje některé skvělé aplikace funkce kari. Podívejte se zde: Currying Up String Funkce

0
Chris West

Souhlasím s tím, že občas byste chtěli dostat míč do pohybu vytvořením pseudo-funkce, která bude mít vždy hodnotu prvního zadaného argumentu. Naštěstí jsem narazil na zcela novou knihovnu JavaScriptu nazvanou jPaq (h ttp: //jpaq.org/ ), která tuto funkci poskytuje. Nejlepší na knihovně je skutečnost, že si můžete stáhnout vlastní sestavu, která obsahuje pouze kód, který budete potřebovat.

0