C# Linq vs. Currying

前端 未结 3 504
南笙
南笙 2021-01-31 20:45

I am playing a little bit with functional programming and the various concepts of it. All this stuff is very interesting. Several times I have read about Currying and what an ad

3条回答
  •  梦如初夏
    2021-01-31 21:05

    what is the advantage of using currying?

    First off, let's clarify some terms. People use "currying" to mean both:

    1. reformulating a method of two parameters into a methods of one parameter that returns a method of one parameter and
    2. partial application of a method of two parameters to produce a method of one parameter.

    Clearly these two tasks are closely related, and hence the confusion. When speaking formally, one ought to restrict "currying" to refer to the first definition, but when speaking informally either usage is common.

    So, if you have a method:

    static int Add(int x, int y) { return x + y; }
    

    you can call it like this:

    int result = Add(2, 3); // 5
    

    You can curry the Add method:

    static Func MakeAdder(int x) { return y => Add(x, y); }
    

    and now:

    Func addTwo = MakeAdder(2);
    int result = addTwo(3); // 5
    

    Partial application is sometimes also called "currying" when speaking informally because it is obviously related:

    Func addTwo = y=>Add(2,y);
    int result = addTwo(3);
    

    You can make a machine that does this process for you:

    static Func PartiallyApply(Func f, A a)
    {
        return (B b)=>f(a, b);
    }
    ...
    Func addTwo = PartiallyApply(Add, 2);
    int result = addTwo(3); // 5
    

    So now we come to your question:

    what is the advantage of using currying?

    The advantage of either technique is that it gives you more flexibility in dealing with methods.

    For example, suppose you are writing an implementation of a path finding algorithm. You might already have a helper method that gives you an approximate distance between two points:

    static double ApproximateDistance(Point p1, Point p2) { ... }
    

    But when you are actually building the algorithm, what you often want to know is what is the distance between the current location and a fixed end point. What the algorithm needs is Func -- what is the distance from the location to the fixed end point? What you have is Func. How are you going to turn what you've got into what you need? With partial application; you partially apply the fixed end point as the first argument to the approximate distance method, and you get out a function that matches what your path finding algorithm needs to consume:

    Func distanceFinder = PartiallyApply(ApproximateDistance, givenEndPoint);
    

    If the ApproximateDistance method had been curried in the first place:

    static Func MakeApproximateDistanceFinder(Point p1) { ... }
    

    Then you would not need to do the partial application yourself; you'd just call MakeApproximateDistanceFinder with the fixed end point and you'd be done.

    Func distanceFinder = MakeApproximateDistanceFinder(givenEndPoint);
    

提交回复
热议问题