Programming

JavaScript 카레 : 실용적인 응용 프로그램은 무엇입니까?

procodes 2020. 5. 25. 21:22
반응형

JavaScript 카레 : 실용적인 응용 프로그램은 무엇입니까?


나는 아직 카레를 먹지 않았다고 생각합니다. 나는 그것이 무엇을하고 어떻게하는지 이해합니다. 나는 그것을 사용할 상황을 생각할 수 없습니다.

JavaScript에서 카레를 사용하는 곳은 어디입니까? DOM 조작 또는 일반적인 응용 프로그램 개발 예제를 환영합니다.

답변 중 하나 는 애니메이션을 언급합니다. 같은 기능은 slideUp, fadeIn인수로 요소를 가지고 일반적으로 내장 된 기본 "애니메이션 기능"과 고차 함수를 반환하는 카레 기능입니다. 일부 기본 설정으로 더 높은 기능을 적용하는 것보다 왜 더 낫습니까?

그것을 사용하는 데 단점이 있습니까?

요청에 따라 JavaScript 커리에 대한 좋은 자료가 있습니다.

의견에서 자라면서 더 추가하겠습니다.


따라서 답변에 따르면 일반적으로 커리 및 부분 적용은 편의 기술입니다.

동일한 구성으로 고수준 함수를 호출하여 자주 "정제"하는 경우, 고수준 함수를 카레 (또는 Resig의 일부 사용)하여 간단하고 간결한 도우미 메서드를 만들 수 있습니다.


@ 행복한 게이

EmbiggensTheMind의 의견에 답변 :

카레 자체만으로도 JavaScript에서 유용한 인스턴스는 생각할 수 없습니다 . 여러 인수를 가진 함수 호출을 각 호출마다 단일 인수를 가진 함수 호출 체인으로 변환하는 기술이지만 JavaScript는 단일 함수 호출에서 여러 인수를 지원합니다.

JavaScript에서는 (람다 미적분학이 아닌) 대부분의 다른 실제 언어를 가정하지만 일반적으로 부분 응용 프로그램과 관련이 있습니다. John Resig 는 더 잘 설명 하지만 요점은 두 개 이상의 인수에 적용될 논리가 있으며 일부 인수에 대한 값만 알고 있다는 것입니다.

부분적 응용 프로그램 / 커링을 사용하여 알려진 값을 수정하고 알 수없는 값만 허용하는 함수를 반환하여 나중에 실제로 전달하려는 값이있을 때 호출 할 수 있습니다. 이렇게하면 동일한 값을 제외한 모든 값을 사용하여 동일한 JavaScript 내장 함수를 반복해서 호출했을 때 자신을 반복하지 않아도됩니다. 요한의 예를 훔치려면 :

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

클로저를 사용하는 JavaScript에서 흥미롭고 실용적인 카레 사용은 다음과 같습니다 .

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"

curry확장은 확장에 의존 Function하지만 사용하는 것만 볼 수 있습니다 apply(너무 화려 하지는 않습니다).

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)));
    }
}

functools.partialJavaScript 와 유사한 파이썬과 유사한 함수를 발견했습니다 .

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));
  };
}

왜 그것을 사용하고 싶습니까? 이것을 사용하려는 일반적인 상황 this은 함수를 값 에 바인딩하려는 경우입니다.

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

콜백이 호출되면를 this가리 킵니다 obj. 이것은 일반적으로 코드가 짧아 지므로 이벤트 상황이나 공간을 절약하는 데 유용합니다.

카레는 카레가 반환하는 함수가 하나의 인수를 받아 들인다는 점을 제외하면 부분적으로 비슷합니다.


Hank Gay에 동의하기-특정 기능 프로그래밍 언어에 매우 유용합니다. 필요한 부분이기 때문입니다. 예를 들어, Haskell에서는 단순히 함수에 여러 개의 매개 변수를 사용할 수 없습니다. 순수한 함수형 프로그래밍에서는 그렇게 할 수 없습니다. 한 번에 하나의 매개 변수를 가져와 함수를 작성하십시오. JavaScript에서는 "converter"와 같은 고안된 예제에도 불구하고 단순히 불필요합니다. 카레를 넣지 않아도 동일한 변환기 코드가 있습니다.

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

나는 "자바 스크립트 : 좋은 부분들"에서 Douglas Crockford가 자신의 핸디 한 말보다는 카레의 역사와 실제 사용에 대해 언급했으면 좋겠다. 그것을 읽은 후 가장 오랫동안, 나는 함수형 프로그래밍을 공부하고 그것이 어디에서 왔는지 깨달을 때까지 혼란에 빠졌습니다.

좀 더 생각한 후에 JavaScript에서 카레를 사용하는 유효한 유스 케이스가 하나 있다고 생각합니다. JavaScript를 사용하여 순수한 함수형 프로그래밍 기술을 사용하여 작성하려는 경우. 그러나 드문 유스 케이스처럼 보입니다.


다음은 예입니다.

JQuery를 사용하여 여러 필드를 계측하여 사용자가 무엇을하고 있는지 확인할 수 있습니다. 코드는 다음과 같습니다.

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

(JQuery가 아닌 사용자의 경우 두 필드가 포커스를 얻거나 잃을 때마다 trackActivity () 함수를 호출하려고합니다. 익명 함수를 사용할 수도 있지만 복제해야합니다. 4 번이나 뽑아서 이름을 붙였습니다.)

이제 이러한 필드 중 하나를 다르게 처리해야합니다. 추적 인프라로 전달되는 해당 호출 중 하나에 매개 변수를 전달하고 싶습니다. 카레와 함께 할 수 있습니다.


It's no magic or anything... just a pleasant shorthand for anonymous functions.

partial(alert, "FOO!") is equivalent to function(){alert("FOO!");}

partial(Math.max, 0) corresponds to function(x){return Math.max(0, x);}

The calls to partial (MochiKit terminology. I think some other libraries give functions a .curry method which does the same thing) look slightly nicer and less noisy than the anonymous functions.


As for libraries using it, there's always Functional.

When is it useful in JS? Probably the same times it is useful in other modern languages, but the only time I can see myself using it is in conjunction with partial application.


I would say that, most probably, all the animation library in JS are using currying. Rather than having to pass for each call a set of impacted elements and a function, describing how the element should behave, to a higher order function that will ensure all the timing stuff, its generally easier for the customer to release, as public API some function like "slideUp", "fadeIn" that takes only elements as arguments, and that are just some curried function returning the high order function with the default "animation function" built-in.


JavaScript functions is called lamda in other functional language. It can be used to compose a new api (more powerful or complext function) to based on another developer's simple input. Curry is just one of the techniques. You can use it to create a simplified api to call a complex api. If you are the develper who use the simplified api (for example you use jQuery to do simple manipulation), you don't need to use curry. But if you want to create the simplified api, curry is your friend. You have to write a javascript framework (like jQuery, mootools) or library, then you can appreciate its power. I wrote a enhanced curry function, at http://blog.semanticsworks.com/2011/03/enhanced-curry-method.html . You don't need to the curry method to do currying, it just help to do currying, but you can always do it manually by writing a function A(){} to return another function B(){}. To make it more interesting, use function B() to return another function C().


I know its old thread but I will have to show how this is being used in javascript libraries:

I will use lodash.js library to describe these concepts concretely.

Example:

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

Partial Application:

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

Currying:

var curriedFn = _.curry(fn);

Binding:

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

usage:

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!

difference:

after currying we get a new function with no parameters pre bound.

after partial application we get a function which is bound with some parameters prebound.

in binding we can bind a context which will be used to replace ‘this’, if not bound default of any function will be window scope.

Advise: There is no need to reinvent the wheel. Partial application/binding/currying are very much related. You can see the difference above. Use this meaning anywhere and people will recognise what you are doing without issues in understanding plus you will have to use less code.


I agree that at times you would like to get the ball rolling by creating a pseudo-function that will always have the value of the first argument filled in. Fortunately, I came across a brand new JavaScript library called jPaq (http://jpaq.org/) which provides this functionality. The best thing about the library is the fact that you can download your own build which contains only the code that you will need.


I just wrote a jPaq example which shows some cool applications of the curry function. Check it out here: Currying Up String Functions


Just wanted to add some resources for Functional.js:

Lecture/conference explaining some applications http://www.youtube.com/watch?v=HAcN3JyQoyY

Updated Functional.js library: https://github.com/loop-recur/FunctionalJS Some nice helpers (sorry new here, no reputation :p): /loop-recur/PreludeJS

I've been using this library a lot recently to reduce the repetition in an js IRC clients helper library. It's great stuff - really helps clean up and simplify code.

In addition, if performance becomes an issue (but this lib is pretty light), it's easy to just rewrite using a native function.


You can use native bind for quick, one line solution

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


Another stab at it, from working with promises.

(Disclaimer: JS noob, coming from the Python world. Even there, currying is not used all that much, but it can come in handy on occasion. So I cribbed the currying function - see links)

First, I am starting with an ajax call. I have some specific processing to do on success, but on failure, I just want to give the user the feedback that calling something resulted in some error. In my actual code, I display the error feedback in a bootstrap panel, but am just using logging here.

I've modified my live url to make this fail.

function ajax_batch(e){
    var url = $(e.target).data("url");

    //induce error
    url = "x" + url;

    var promise_details = $.ajax(
        url,
        {
            headers: { Accept : "application/json" },
            // accepts : "application/json",
            beforeSend: function (request) {
                if (!this.crossDomain) {
                    request.setRequestHeader("X-CSRFToken", csrf_token);
                }
        },
        dataType : "json",
        type : "POST"}
    );
    promise_details.then(notify_batch_success, fail_status_specific_to_batch);
}

Now, here in order to tell the user that a batch failed, I need to write that info in the error handler, because all it is getting is a response from the server.

I still only have the info available at coding time - in my case I have a number of possible batches, but I don't know which one has failed w.o. parsing the server response about the failed url.

function fail_status_specific_to_batch(d){
    console.log("bad batch run, dude");
    console.log("response.status:" + d.status);
}

Let's do it. Console output is:

console:

bad batch run, dude utility.js (line 109) response.status:404

Now, let's change things a bit and use a reusable generic failure handler, but also one that is curried at runtime with both the known-at-code-time calling context and the run-time info available from event.

    ... rest is as before...
    var target = $(e.target).text();
    var context = {"user_msg": "bad batch run, dude.  you were calling :" + target};
    var contexted_fail_notification = curry(generic_fail, context); 

    promise_details.then(notify_batch_success, contexted_fail_notification);
}

function generic_fail(context, d){
    console.log(context);
    console.log("response.status:" + d.status);
}

function curry(fn) {
     var slice = Array.prototype.slice,
        stored_args = slice.call(arguments, 1);
     return function () {
        var new_args = slice.call(arguments),
              args = stored_args.concat(new_args);
        return fn.apply(null, args);
     };
}

console:

Object { user_msg="bad batch run, dude. you were calling :Run ACL now"} utility.js (line 117) response.status:404 utility.js (line 118)

More generally, given how widespread callback usage is in JS, currying seems like a quite useful tool to have.

https://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/ http://www.drdobbs.com/open-source/currying-and-partial-functions-in-javasc/231001821?pgno=2

참고URL : https://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications

반응형