关于柯里化(curry)

在实际使用的过程中对柯里化有了一些无法从书本上直接获得的感受。

在JAVA中函数不是头等公民,必须通过接口进行外观统一以后,才能通过实例作为载体进行处理逻辑的传递,

最容易理解的例子莫过于Strategy Pattern,这里就不复述这个概念了。

但是实际上大家都应该遇见过参数个数或者类型无法完全统一的困扰,这个时候我们是怎么办的呢?参数个数不统一,我们可以通过使用构造函数在生成实例的时候传递进去,参数类型不统一的话只能通过Adaptor或者额外抽象出一层来解决,在JAVA中也只能做到这样了。

如何避免这个问题的呢?需要两个前提:1.函数是头等公民可以自由传递;2.柯里化

看起来函数式完全符合要求,这两个前提的组合下可以很轻量的解决我们在JAVA中预见的问题:

  def commonOp[T](list: List[T])(f: List[T] => List[T]): Option[List[T]] = {
    list match {
      case h :: t => Some(f(t))
      case _ => None
    }
  }

  val list = List(1, 3, 4, 5)

  val tailer = (list: List[Int]) => list
  val adder = (list: List[Int]) => (n: Int) => n :: list

  println(commonOp(list)((list: List[Int]) => list))
  println(commonOp(list)(adder(_)(5)))

例子可能有些牵强,但这里只是想表达柯里化如何工作而已,不必在意。

tailer传入一个List,不做任何处理直接返回

adder传入一个List和一个n,把n作为头加在list的前面

commonOp两个参数,list和处理list的function,其中function的入参是list,出参也是list

上面的tailer和adder都需要带入到commonOp的第二个function函数参数中。

commonOp的function函数参数实际的类型是Function1,tailer直接带入没有问题,但是adder就不行了,

所以要在外部将adder变成一个偏应用函数,先传入n之后,类型从Function2变成了Function1,柯里化其实就是可以改变函数的FunctionN的类型。

很轻巧,和JAVA的重量天壤之别。

时间: 2024-10-09 22:28:17

关于柯里化(curry)的相关文章

Effective JavaScript Item 26 使用bind来进行函数的柯里化(Curry)

本系列作为Effective JavaScript的读书笔记. 在上一个Item中介绍了bind的一种用法:用来绑定this对象.但是实际上,bind含有另一种用法,就是帮助函数进行柯里化.关于柯里化,这里有一份百科可以参考: http://zh.wikipedia.org/wiki/%E6%9F%AF%E9%87%8C%E5%8C%96 但是实际上,关于柯里化只需要记住一点就够了:柯里化是把接受多个参数的函数变换成接受一个单一参数(通常是最初函数的第一个参数,但是并无限制)的函数,并且返回这个

JavaScript函数柯里化的一些思考

1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函数f1和f是等效的,我们直接令var f1 = f;就行了,完全没有必要包裹那么一层. 但是,下面一段代码就未必能够看得出问题来了: var getServerStuff = function(callback){ return ajaxCall(function(json){ return cal

Scala函数柯里化(Currying or Curry)

柯里化(Currying) 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 简单的实现如下: scala> def add(x:Int, y:Int) = x + y add: (x: Int, y: Int)Int 假如我们应用的时候,是这样的:add(1,2) 柯里化函数: scala> def add(x:Int)(y:Int) = x + y Curry化最大的意义在于把多个参数的function等价转化成多

JS中的柯里化(currying)

何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果.因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程. 柯里化一个求和函数 按照分步求值,我们看一个简单的例子 var concat3Words = function (a

浅谈JavaScript中的柯里化函数

首先,不可避免的要引经据典啦,什么是柯里化函数呢(from baidu): 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的. 用于创建已经设置好了一个或多个参数的函数 与函数绑定相似,他们之间的区

建议75:函数柯里化

柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回一个新函数,这个新函数能够接受原函数的参数.下面可以通过例子来帮助理解.function adder(num) {    return function(x) {        return num + x;    }}var add5 = adder(5);var add6 = adder(6);print(add5(1));  // 6print(add6(1));  //7 函数adder接受一个参数,并返回一个函数,这个返

【读书笔记】 函数柯里化

这是书上函数柯里化的例子 1 function curry(fn){ 2 var args = Array.prototype.slice.call(arguments, 1);//取出调用curry时除了第一个函数参数的后面所有参数; 3 return function(){ 4 var innerArgs = Array.prototype.slice.call(arguments);//取出第二次调用时的所有参数; 5 var finalArgs = args.concat(innerAr

一道javascript面试题(闭包与函数柯里化)

要求写一个函数add(),分别实现能如下效果: (1)console.log(add(1)(2)(3)(4)());//10 (2)console.log(add(1,2)(3,4)());//10 (3)console.log(add(1,2)(3,4));//10 针对(1)和(2),有两种思路实现:纯闭包思路和函数柯里化思路.一.闭包思路 (1)的解决方案(闭包实现) function add(arg) { // body... let sum = 0; sum+=arg; return

柯里化

柯里化 将多参数函数分为较小的一个参数函数 在一些基本类型的题外话之后,我们再次回到函数上,特别是我们前面提到的难题,如果数学函数只能有一个参数,那么F#的函数怎么能有多个参数? 答案很简单:多参数的函数被重写成一系列的单个参数的新函数.这是编译器为你自动完成的.一个在函数式编程中有重要影响的数学家,Haskell Curry之后,被称为"柯里化". 我们用一个打印两个数字的基本实例,看看在实际中它是怎么运行的: let printTwoParameters x y = printfn