`
bit1129
  • 浏览: 1068051 次
  • 性别: 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-2.12.6.tgz

    它支持高阶函数、柯里化、尾递归优化和不可变数据结构,这些都是函数式编程的核心概念。 9. 特性与模式: Scala还引入了一些独特的语言特性,如特质(Traits)、隐式转换和case类,这些帮助开发者实现更简洁、更具...

    spark源码之scala基础语法demo

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

    Scala 函数柯里化(Currying)

    首先我们定义一个函数: def add(x:Int,y:Int)=x+y 那么我们应用的时候,应该是这样用:add(1,2) 现在我们把这个函数变一下形: def add(x:Int)(y:Int) = x + y 那么我们应用的时候,应该是这样用:add(1)(2),最后...

    Scala程序设计第二版

    3. **函数式编程**:Scala对函数式编程的支持是其一大特色,包括高阶函数、匿名函数、闭包、函数作为一等公民、柯里化、尾递归优化等。书本将详细解释这些概念及其在Scala中的应用。 4. **模式匹配**:Scala的模式...

    scala sdk scala-2.12.3

    同时,Scala还提供了函数式编程的关键概念,如高阶函数、闭包和柯里化。 10. **Actor模型**:Akka库是Scala中的并发和分布式计算框架,基于Actor模型,使得编写高性能、容错的应用程序变得简单。 11. **Dotty/...

    快学Scala课后习题答案

    6. **函数式编程**:Scala的函数式编程特性包括柯里化、尾递归、闭包和monads等。例如,`f.curry` 将一个接受两个参数的函数转换为接受一个参数并返回另一个函数的形式。 7. ** Actors模型**:Scala提供了内置的...

    Scala与Clojure函数式编程模式:Java虚拟机高效编程1

    4. **柯里化**:将接受多个参数的函数转换为一系列接受单个参数的函数,增强了函数的组合性。 5. **函数组合**:通过将多个简单函数串联起来创建复杂功能,保持代码清晰。 6. **递归**:函数调用自身解决问题,常见...

    scala-2.12.14.zip&scala-2.12.11.tgz Linux版本压缩包.rar

    3. **函数式编程**:支持高阶函数、柯里化、尾递归优化等特性,使得代码简洁且易于测试。 4. ** Actors模型**:提供了一种轻量级的并发机制,用于实现高效的并行和分布式计算。 5. **集合库**:Scala的集合库强大且...

    scala高级特性

    在函数式编程语言中,函数是“头等公民”,高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。 作为值的函数 作为值的函数可以像任何其他数据类型一样被传递和操作的函数。定义函数时的格式为:`val 变量...

    Scala考试题1

    - 柯里化是将接受多个参数的函数转换为一系列只接受一个参数的函数的过程。 13. **模式匹配与 Java switch-case 的不同**: - Scala 的模式匹配更强大,支持值匹配、类型匹配、提取器对象等,而 Java 的 switch-...

    scala实战高清讲解

    - 柯里化:Scala支持柯里化,即将接受多个参数的函数转化为一系列接受一个参数的函数,增强了函数的灵活性。 - 纯函数:纯函数没有副作用,只依赖于输入参数,不改变外部状态,有助于写出可预测且易于测试的代码。...

    scala2.12.1Windows镜像包

    并支持高阶函数、柯里化、闭包等概念。 - **模式匹配**:强大的模式匹配机制,用于解构复杂数据结构。 - ** Actors模型**:Scala内置对Akka框架的支持,允许并发编程时使用Actors模型,简化了并发控制。 2. **...

    Scala函数式编

    在Scala中,函数式编程是其核心特性之一,它允许开发者以一种声明式而非命令式的方式处理问题,从而提高代码的可读性和可维护性。本文将深入探讨Scala中的函数式编程概念、语法以及其实现方式。 函数作为一等公民 ...

    scala-2.11.8.tgz

    - 学习函数式编程,理解其核心概念如柯里化、尾递归、monads等。 此外,Scala-2.11.8对Java 8的支持意味着你可以利用Lambda表达式、Stream API等新特性,使得与Java代码的互操作变得更加顺畅。 总之,`scala-...

    Scala最新官方下载包(官方的下载真的慢)

    3. **函数式编程**:Scala是函数式编程的强大平台,支持高阶函数、不可变数据结构和柯里化。函数可以作为一等公民,即函数可以赋值给变量,作为参数传递,也可以作为返回值。 4. **模式匹配**:Scala提供了强大的...

    Scala编程.zip

    2. **函数式编程**:讲解不可变性、柯里化、高阶函数、闭包、递归等函数式编程核心概念。 3. **并发编程**:介绍Scala的Actor模型和Future API,以及如何在多线程环境中高效地操作数据。 4. **Scala与Spark集成**:...

    Scala-2.11.1.zip

    3. **函数式编程**:Scala是函数式编程的强大平台,它提供了高阶函数、匿名函数、柯里化、尾递归优化等功能。函数在Scala中被视为一等公民,可以作为参数传递,也可以作为返回值。 4. **集合库**:Scala的集合库是...

    韩顺平_Scala语言核心编程 .zip

    它有高阶函数、闭包、柯里化(Currying)以及不可变数据结构等特性。函数式编程让代码更简洁、可读性更强,同时也易于测试和并行化。 3. **类型系统**:Scala的类型系统是静态的,它能够进行类型推断,使得代码更...

    Scala函数式编程 2016年4月 电子工业出版

    1. 纯函数:函数不产生副作用,每次相同的输入都会得到相同的输出,这使得函数更加可靠和易于测试。 2. 不可变性:在函数式编程中,数据结构通常是不可变的,这有助于简化并发编程,减少竞态条件和死锁的问题。 3. ...

Global site tag (gtag.js) - Google Analytics