`
bit1129
  • 浏览: 1050713 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Scala十六】Scala核心十:柯里化函数

 
阅读更多

本篇文章重点说明什么是函数柯里化,这个语法现象的背后动机是什么,有什么样的应用场景,以及与部分应用函数(Partial Applied Function)之间的联系

 

1. 什么是柯里化函数

A way to write functions with multiple parameter lists. For instance
def f(x: Int)(y: Int) is a curried function with two parameter
lists. A curried function is applied by passing several arguments
lists, as in: f(3)(4). However, it is also possible to write a partial
application of a curried function, such as f(3).

也就是说,有多个参数列表 的函数就是柯里化函数,所谓的参数列表就是使用小括号括起来的函数参数列表

 

2. 柯里化函数的设计动机

每个语言现象都有它的动机,即为解决什么问题而引入了柯里化函数这个语言现象

 

以如下的柯里化函数sum为例,Scala在执行sum(1)(2)的时候,实际上是执行了两次函数调用,首先执行sum(1)_返回一个函数,这个函数是一个部分应用函数,为这个部分应用函数提供参数2后,得到结果

scala> def sum(x:Int)(y:Int)=x+y
sum: (x: Int)(y: Int)Int
               
scala> val second = sum(1)_
second: Int => Int = <function1>

scala> second(2)
res1: Int = 3

scala>

 

sum(1)_这个偏函数表示的是第二个函数

 

柯里化函数执行时,分解为两个函数执行,步骤与下面的方法调用过程类似

 

scala> def first(x:Int) = (y:Int)=>x+y
first: (x: Int)Int => Int

scala> val second = first(1)
second: Int => Int = <function1>

scala> second(2)
res4: Int = 3

  

柯里化实现Java7的try-with-resources控制结构

 

package spark.examples.scala

import java.io.FileInputStream

object CurryTest {
  def withIOStream(stream: java.io.InputStream)(func: java.io.InputStream => Unit) {
    try {
      func(stream)
    } finally {
      stream.close()
    }
  }

  def read(stream: java.io.InputStream) = {
    println(stream.available())
  }

  def main(args: Array[String]) {
    withIOStream(new FileInputStream("d:/people.txt")) {
      println("Hello,Start to read")
      read
    }
  }

 

柯里化函数withIOStream中的func参数也可以和stream放在一起,使得withIOStream成为一个普通的函数,但是使用者在用的时候,就无法实现像CurryTest中使用的那样体现Java7的try-with-resource风格,具有明显的代码控制结构的意味在里面。

 

 

curry化最大的意义在于把多个参数的function等价转化成多个单参数function的级联,这样所有的函数就都统一了,方便做lambda演算。 在scala里,curry化对类型推演也有帮助,scala的类型推演是局部的,在同一个参数列表中后面的参数不能借助前面的参数类型进行推演,curry化以后,放在两个参数列表里,后面一个参数列表里的参数可以借助前面一个参数列表里的参数类型进行推演。这就是为什么 foldLeft这种函数的定义都是curry的形式

 

 

 

object FoldLeftRightTest {
 def main(args: Array[String]) {
    val list = List(1, 3, 5)

    //折叠操作是一个递归的过程,将上一次的计算结果代入到函数中
    //作为结果的参数在foldLeft是第一个参数,在foldRight是第二个参数

    //foldLeft表示从左向右折叠,从最左边的元素向最右边的元素折叠
    val c = list.foldLeft("String:")((x: String, y: Int) => x + y) //String:135
    println(c)

    val cc = list.foldLeft("String:")((x: String, y: Int) => y + x) //531String:
    println(cc)

    /* /:是foldLeft的符号表示*/
    val ccc = list./:("String:")((x: String, y: Int) => x + y) //String:135
    println(ccc)

    val d = list.foldLeft(100)((x: Int, y: Int) => x + y) //109
    println(d)

    //foldRight表示从右向左折叠,从最右边的元素向最左边的元素折叠
    val e = list.foldRight("String:")((y: Int, x: String) => x + y) //String:531
    println(e)

    val f = list.foldRight("String:")((y: Int, x: String) => y + x) //135String:
    println(f)

    //:\是foldRight的符号表示
    val g = list.:\("String:")((y: Int, x: String) => y + x) //135String:
    println(g)
  }
}
 

 关于柯里化函数类型推演的例子:

 

class A {
  class B
}

object CurryTest {
  //定义为柯里化函数时没有问题的,b的类型可以由a参与得出
  def method(a: A)(b: a.B) {

  }

  //参数列表的第二个参数,a没有定义,不能参与b的类型推断
  def method2(a: A, b: a.B /*a is not defined in a.B*/) {

  }

  def main(args: Array[String]) {

  }
}

 

 

 

分享到:
评论

相关推荐

    Scala函数式编程

    《Scala函数式编程》是针对希望学习FP并将它应用于日常编码中的程序员而写的,内容包括:函数式编程的概念;函数式编程相关的各种“为什么”和“怎么做”;如何编写多核程序;练习和检测。 从OOP到FP,思路的转化 ...

    spark源码之scala基础语法demo

    scala是一种基于JVM的面向对象的函数编程,scala编程相对于...2:函数式编程,柯里化函数,匿名函数,高阶函数等。 3:代码行简单。 4:支持并发控制,Actor Model机制 5:目前比较流行的kafka,spark均由scala开发。

    Scala 函数柯里化(Currying)

    柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。 实例 首先我们定义一个函数: def add(x:Int,y:Int)=x+y 那么我们应用的时候,...

    Scala编程详解 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    scala-xml_2.11-1.0.4-API文档-中英对照版.zip

    赠送jar包:scala-xml_2.11-1.0.4.jar; 赠送原API文档:scala-xml_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.4-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.4.pom; 包含翻译后的API...

    scala-xml_2.12-1.0.6-API文档-中文版.zip

    赠送jar包:scala-xml_2.12-1.0.6.jar; 赠送原API文档:scala-xml_2.12-1.0.6-javadoc.jar; 赠送源代码:scala-xml_2.12-1.0.6-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.12-1.0.6.pom; 包含翻译后的API...

    Scala函数式编程.pdf

    函数式编程(FP)是一种...《Scala函数式编程》是针对希望学习FP并将它应用于日常编码中的程序员而写的,内容包括:函数式编程的概念;函数式编程相关的各种“为什么”和“怎么做”;如何编写多核程序;练习和检测。

    scala-parser-combinators-2.11-1.0.4-API文档-中文版.zip

    赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 赠送Maven依赖信息...

    Scala编程详解 第21讲-Scala编程详解:Actor入门 共8页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    Scala编程详解 第19讲-Scala编程详解:类型参数 共13页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    scala-parser-combinators_2.11-1.0.4-API文档-中英对照版.zip

    赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 包含翻译后的API...

    Scala编程详解 第4讲-Scala编程详解:条件控制与循环 共7页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    Scala编程详解 第14讲-Scala编程详解:面向对象编程之继承 共13页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    Scala编程详解 第13讲-Scala编程详解:面向对象编程之对象 共9页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    Scala编程详解 第12讲-Scala编程详解:面向对象编程之类 共12页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    Scala编程详解 第9讲-Scala编程详解:数组操作之Array、ArrayBuffer以及遍历数组 共7页.pptx

    第5讲-Scala编程详解:函数入门 共5页 第6讲-Scala编程详解:函数入门之默认参数和带名参数 共5页 第7讲-Scala编程详解:函数入门之变长参数 共4页 第8讲-Scala编程详解:函数入门之过程、lazy值和异常 共5页 第9讲-...

    scala-java8-compat_2.11-0.7.0-API文档-中文版.zip

    赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...

Global site tag (gtag.js) - Google Analytics