JavaScript支持部分功能应用吗?

Jas*_*rez 8 javascript functional-programming

阅读关于First-Class函数的维基百科文章,有一个很好的语言支持表,用于函数式编程的各个方面:http://en.wikipedia.org/wiki/First-class_function#Language_support

JavaScript被列为没有部分功能应用程序.但是,有一些技术可用于创建一个函数,该函数返回一个函数,该函数具有一些存储在闭包中的参数,即:

var add = function(a, b){
    return a + b;
},
apply = function(fn, a){
    return function(b){ 
        return fn(a, b); 
    }
},
addFive = apply(add, 5);

console.log(addFive(2)); // prints 7
Run Code Online (Sandbox Code Playgroud)

这不是部分功能应用吗?如果没有,有人可以提供另一种语言的部分功能应用的例子,并解释它是如何不同的?

谢谢!

LiK*_*Kao 6

你应该注意理解这个概念叫做currying(在Haskell B. Curry之后).在n + 1个参数的函数和一个参数的函数之间存在同构,其中一个参数返回具有n个参数的函数.如果您以递归方式应用此参数,则可以编写任意数量参数的函数作为函数的函数.

这就是为什么在函数式语言功能通常类型为X -> Y -> Z意义,这是一个函数,该函数X返回一个函数取Y返回Z.这个签名也意味着你可以只提供一个X并且该函数将返回一个函数本身.

在Javascript中,两个参数的函数将具有签名,X * Y -> Z这意味着它是一个带有一对的函数X * Y并返回一个Z.但是你不能提供半对.

有两种方法:

有了这个,你现在有了一个功能,它具有Int -> Int -> Int部分功能应用所需的实际信号.但是你还必须确保调用这个curryadd(5)(10)不自然的函数.

  • 提供更高阶的功能,这可以满足您的功能需求.在你的情况下,apply会做两件事,它会影响你的add函数并绑定参数.这可以分为两部分:

    var curry = function(fn) {
        return function(a){ return function(b){ return fn(a,b); } }
    };
    
    Run Code Online (Sandbox Code Playgroud)

这实际上将实现具有对作为参数的函数和返回函数的函数之间的同构.还有一种写法可以uncurry向后做同样的事情.

因为你必须手动完成所有这些并且没有直接的语言支持,所以javascript被认为没有部分功能应用程序(这并不表示你不能将它添加到语言中).


dec*_*eze 5

您展示的是高阶函数的示例,函数将函数作为参数和/或返回函数.

部分应用是不同的.这是一个Haskell示例:

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

addOne = add 1
Run Code Online (Sandbox Code Playgroud)

add是一个函数,取两个Int并返回一个Int,表示为Int -> Int -> Int.如果您不熟悉语法,在Javascript中大致如下所示:

/**
 * @param int x
 * @param int y
 * @return int
 */
function add(x, y) {
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

add 1仅使用一个参数调用此函数,该参数返回一个新函数,该函数取一个Int并返回一个Int(Int -> Int).该add函数未明确设计为更高阶函数,只是部分应用.


And*_*dre 5

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

var func2 = func1.bind(undefined, 3);

func2(1); // 4
func2(2); // 5
func2(3); // 6
Run Code Online (Sandbox Code Playgroud)

检查developer.mozilla.org上的文档