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. Android编译系统入门(一)

    做过Android平台开发的朋友对make,mm或make clean命令应该很熟悉,但也许大家只是熟知这些命令的作用却不知道这些命令底下有些什么原理?那么今天我就带着大家推开Android编译系统的 ...

  2. 巨蟒python全栈开发-第14天 内置函数2 递归 二分查找

    一.今日内容总览 1.内置函数补充 repr() 显示出字符串的官方表示形式 chr() arscii码中的字,转换成位置 ord() arscii码中的位置,转换成字2.递归 自己调用自己 两个口: ...

  3. 【转】windows 下 goprotobuf 的安装与使用

    1. 安装 在网上看了很多教程,都提到要安装 protoc 与 protoc-gen-go,但通过尝试之后并不能正确安装 protoc,一下记录能够顺利安装 protoc 与 protoc-gen-g ...

  4. python scrapy,beautifulsoup,regex,sgmparser,request,connection

    In [2]: import requests   In [3]: s = requests.Session()   In [4]: s.headers 如果你是爬虫相关的业务?抓取的网站还各种各样, ...

  5. MySQL数据库(4)- 多表查询、可视化工具Navicat的使用、设计模式MVC

    一.多表查询 准备工作:创建两张表,部门表(department).员工表(employee),代码和表格如下: # 创建表 create table department( id int, name ...

  6. 005-JSX简介以及使用

    一.概述 考虑这个变量声明: const element = <h1>Hello, world!</h1>; 标签语法既不是字符串也不是HTML. 它被称为JSX,它是Java ...

  7. STL 中的链表排序

    一直以来学习排序算法, 都没有在链表排序上下太多功夫,因为用得不多.最近看STL源码,才发现,原来即使是链表,也能有时间复杂度为O(nlogn)的算法, 大大出乎我的意料之外,一般就能想到个插入排序. ...

  8. mongo常用查询

    复杂查询: and: or: lte,gte,=: and+lt:  , 逗号表示and, $lt小于写在值当中 查询实例: 找到含有指定数据文档 查找条件spcode有1个字符长度的文档 db.sp ...

  9. Bootstrap实现的页面

    实现的效果如图,使用bootstrap需要至少三个文件 去bootstrap网上下载,然后使用这三个文件可以了 使用方式,通过标签,class命名来引用已经定制好的html样式 <!DOCTYP ...

  10. PHP iconv函数

    最近在做一个程序,需要用到iconv函数把抓取来过的utf-8编码的页面转成gb2312, 发现只有用iconv函数把抓取过来的数据一转码数据就会无缘无故的少一些. iconv函数库能够完成各种字符集 ...