Does JavaScript support partial function application?

后端 未结 4 710
盖世英雄少女心
盖世英雄少女心 2021-01-05 01:18

Reading through the Wikipedia article on First-Class functions, there is a nice table of language support for various aspects of functional programming: http://en.wikipedia.

相关标签:
4条回答
  • 2021-01-05 01:41

    What you show is an example of higher order functions, functions that take functions as arguments and/or return functions.

    Partial application is something different. Here a Haskell example:

    add     :: Int -> Int -> Int
    add x y = x + y
    
    addOne = add 1
    

    add is a function that takes two Int and returns an Int, denoted as Int -> Int -> Int. If you're unfamiliar with the syntax, in Javascript this would roughly look like this:

    /**
     * @param int x
     * @param int y
     * @return int
     */
    function add(x, y) {
        return x + y;
    }
    

    add 1 calls this function with only one parameter, which returns a new function that takes one Int and returns an Int (Int -> Int). The add function was not explicitly designed to be a higher order function, it was simply partially applied.

    0 讨论(0)
  • 2021-01-05 01:46

    As noted in the other answers, what you describe is currying; it is a form of partial application, as you identify.

    However, if what you want is just partial application, you can use underscore.js, which adds a lot functional programming utilities: http://documentcloud.github.com/underscore/

    0 讨论(0)
  • 2021-01-05 01:47

    The concept you should look up to understand this is called currying (after Haskell B. Curry). There is an isomorphism between functions of n+1 parameters and a function with one parameter returning a function with n parameters. If you apply this recursivly you can write a function of any number of parameters as a function to function to functions.

    This is why functions in functional languages are usually typed as X -> Y -> Z meaning, this is a function which takes a X and returns a function taking a Y returning a Z. This signature also means you can just supply a X and the function will return a function itself.

    In Javascript a function of two parameters will have the signature X * Y -> Z meaning it is a function taking a pair of X * Y and returns a Z. However you cannot supply half a pair.

    There are two ways out of this:

    • Always manually curry your function. Your add function could be written as:

      var curryadd = function(a){
          return function(b){ return a + b; }
      };
      

    With this you now have a function which has the actual signatur Int -> Int -> Int which is needed for partial function application. However you also have to make sure to call this function as curryadd(5)(10) which is unnatural to do.

    • Supply higher order functions, which curry your functions. In your case the apply does two things, it curries your add function and binds the parameter. This can be divided in two parts:

      var curry = function(fn) {
          return function(a){ return function(b){ return fn(a,b); } }
      };
      

    This will actually implement the isomorphism between functions with pairs as arguments and functions which return functions. There also is a way to write uncurry which does the same thing backwards.

    Because you have to do all this manually and there is no direct language support, javascript is said not to have partial function application (which does not say you can't add it to the language).

    0 讨论(0)
  • 2021-01-05 01:56
    var func1 = function(a, b) {
      return a + b;
    }
    
    var func2 = func1.bind(undefined, 3);
    
    func2(1); // 4
    func2(2); // 5
    func2(3); // 6
    

    check docs at developer.mozilla.org

    0 讨论(0)
提交回复
热议问题