curry翻译为中文就是咖喱。意为使用curry可以让代码更有味道。

scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表。也就是说我们要编写的函数不是只有一个参数列表,这个参数列表中有多个参数以逗号分隔;而是一个函数中有多个参数列表,每个参数列表中只有一个参数(当然,也可以有多个参数)。也就是说我们写的函数不再只是这样子的:

def foo(a: Int, b: Int, c: Int) {}

而是这样子的:foo(1)(2)(3),或者这样的:foo(1){2}{3},甚至是这样子的:foo{1}{2}{3}。

来看一下定义成多个参数列表的方法到底是什么样的。这次使用scala交互式shell会话:

按照上面所说我们定义了一个函数foo()。然后,调用foo_创建了一个偏应用函数,也就是说,这个函数有一个或多个参数未绑定。关于偏应用函数稍后会详细说,这次主要关注交互式shell提供的消息:先是三个一连串的转换,链中的每个函数都接收一个Int,返回一个偏应用函数。不过,最后一个的结果是Unit。

现在可以使用curry化的形式重写一下inject方法:

def inject(arr: Array[Int], initial: Int)(operation: (Int, Int) => Int): Int = {
var carryOver = initial
arr.foreach(element => carryOver = operation(carryOver, element))
carryOver
}

这样一来,我们就不必在一个参数列表里用逗号分割的形式传递参数了。现在可以使用圆括号或花括号独立传递参数了:

val array = Array(2, 3, 5, 1, 6, 4)
val sum = inject(array, array(0)){
(carryOver, elem) => Math.max(carryOver, elem)
}
println("Max of elements in array [" + array.mkString(",") + "] is " + sum)

是不是看起来更优雅了——虽然刚见到的时候理解有些困难,但是熟悉了这种语法后还是能体会到它的好处的。

########

scala学习手记25 - Curry化的更多相关文章

  1. scala学习手记24 - 多参数函数值

    上一节的函数值只有一个参数.函数值当然也是可以有多个参数的.看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: ( ...

  2. scala学习手记38 - 方法命名约定和for表达式

    方法命名约定 之前在学习<运算符重载>一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级.现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例. ...

  3. scala学习手记23 - 函数值

    scala的一个最主要的特性就是支持函数编程.函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套.这些高阶函数称为函数值. 举一个简单的例子 ...

  4. scala学习手记17 - 容器和类型推断

    关于scala的类型推断前面已经提到过多次.再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var ...

  5. scala学习手记8 - 自适应的默认做法

    scala有一些默认做法,会让代码更简洁.更易读写,下面列出了这样几个特性: 1. 支持脚本.scala支持脚本,因此无须将所有的代码都放到类里.如果脚本可以满足需求,就将代码放到一个脚本里,无须再创 ...

  6. Scala学习手记1 - 快速体验

    又重新开始了scala的学习,因为中断了太长时间,所以这次还得从零开始.学习的过程就记录在这个博客上了. 这次学习的教程是<scala程序设计 java虚拟机多核编程实战>,我在多看上买了 ...

  7. scala学习手记40 - 使用case类

    前面两节我们已经多次接触过case关键字了.case关键字不仅可以用在match/case中来执行模式匹配,也可以用来修饰类.不过用case修饰的类也主要是用来做模式匹配.在上一节曾经提到过match ...

  8. scala学习手记40 - case表达式里的模式变量和常量

    再来看一下之前的一段代码: def process(input: Any) { input match { case (a: Int, b: Int) => println("Proc ...

  9. scala学习手记39 - 模式匹配

    在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即ma ...

随机推荐

  1. Powershell调用RemoteExchange.ps1

    If ((Get-PSSnapin | where {$_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" ...

  2. wget -d --header

    wget -d --header="Host:www.sina.com" http://202.108.33.84 domain differ ip 防止Wget递归下载 假设Ng ...

  3. Apache Tez Design

    http://tez.incubator.apache.org/ http://dongxicheng.org/mapreduce-nextgen/apache-tez/ http://dongxic ...

  4. IO流入门-第二章-FileOutputStream

    FileOutputStreamj基本用法和方法示例 /* java.io.OutputStream java.io.FileOutputStream 文件字节输出流 将计算机内存中的数据写入到硬盘文 ...

  5. Python菜鸟之路:原生Ajax/Jquery Ajax/IFrame Ajax的选用

    原生Ajax Jquery Ajax IFrame Ajax 如果发送的是普通的数据,比如用户简单的输入.选择的值,推荐使用Jquery ,其次用XMLHttpRquest对象,最次使用IFrame ...

  6. 用jq实现鼠标移入按钮背景渐变其他的背景效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 从es中拉取全部数据/大量数据 使用scroll+scan避免深分页

    es一次请求默认返回的数据条数是10条,可以通过设置size参数来控制返回数据的条数: 如果要返回很多数据,可以把size设置的很大,不过elastic search默认size最大不能超过1万. 那 ...

  8. 【我的Android进阶之旅】Android使用getIdentifier()方法根据资源名来获取资源id

    有时候我们想动态的根据一个资源名获得到对应的资源id,就可以使用getResources().getIdentifier()方法来获取该id.然后再使用该id进行相关的操作. 1.Demo示例 下面用 ...

  9. DBCC SHRINKFILE收缩日志/收缩数据库/收缩文件

    DBCC SHRINKFILE 收缩相关数据库的指定数据文件或日志文件大小. 语法 DBCC SHRINKFILE    ( { file_name | file_id }        { [ ,t ...

  10. TypeScript学习笔记—数据类型

    TypeScript 数据类型 Boolean 类型 let isDone: boolean = false; // tsc => var isDone = false; Number 类型 l ...