文章目录
  1. 1. 函数式编程的基本函数
    1. 1.1. 筛选(Filter)
    2. 1.2. 映射(map)
    3. 1.3. 折叠/化约(reduce)
  2. 2. 责权让渡
    1. 2.1. 迭代让位于高阶函数
    2. 2.2. 闭包(closure)
    3. 2.3. 柯里化(currying)和函数的部分施用(partial application)
    4. 2.4. 递归
    5. 2.5. Stream和作业顺序重排
  3. 3. 函数式语言常见特性
    1. 3.1. 记忆(memoization)
    2. 3.2. 惰性求值(laziness)
  4. 4. 演化的语言
    1. 4.1. 少量的数据结构搭配大量的操作
    2. 4.2. 函数式的数据结构
      1. 4.2.1. 函数式的异常处理
      2. 4.2.2. Either类
      3. 4.2.3. Option类
  5. 5. 模式与重用
    1. 5.1. 模版方法(Template Method)模式
    2. 5.2. 策略(Strategy Method)模式
    3. 5.3. 享元(Flyweight)模式
    4. 5.4. 工厂(Factory)模式和柯里化
  6. 6. 现实应用
    1. 6.1. Java8
    2. 6.2. 函数式的基础设施
      1. 6.2.1. 架构
      2. 6.2.2. Web框架
      3. 6.2.3. 数据库
  7. 7. 多语言与多范式
  8. 8. 参考

函数式编程的基本函数

筛选(Filter)

  • scala

    filter()

    1
    2
    3
    val numbers = List.range(1, 11)
    numbers filter (x => x % 3 == 0)
    // List (3, 6, 9)
    1
    2
    3
    val numbers = list.range(1, 11)
    numbers filter (_ % 3 == 0)
    // List (3, 6, 9)

    partition()

    1
    2
    3
    numbers partition (_ % 3 == 0)
    // (List(3, 6, 9), List(1, 2, 4, 5, 7, 8, 10))

    find()

    1
    2
    numbers find (_ % 3 == 0)
    // Some(3)

    takeWhile()

    1
    2
    List(1, 2, 3, -4, 5, 6, 7) takeWhile (_ > 0)
    // List(1, 2, 3)

    dropWhile()

    1
    2
    List(1, 2, 3, -4, 5, 6, 7) dropWhile (_ > 0)
    // List(5, 6, 7)

映射(map)

  • scala

    map()

    1
    2
    List(1, 2, 3) map (_ + 1)
    // List(2, 3, 4)

    flatMap()

    1
    2
    List(List(1, 2, 3), List(4, 5, 6)) flatMap(_.toList)
    // List(1, 2, 3, 4, 5, 6)

折叠/化约(reduce)

  • scala

    reduceLeft()

    1
    2
    List.range(1, 10).reduceLeft(0)(_ + _)
    // 45

    reduceRight()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    List.range(1 ,10).reduceRight(_ - _)
    // 8 - 9 = -1
    // 7 - (-1) = 8
    // 6 - 8 = -2
    // 5 - (-2) = 7
    // 4 - 7 = -3
    // 3 - (-3) = 6
    // 2 - 6 = -4
    // 1 - (-4) = 5
    // 5

    foldLeft()

    1
    2
    List.range(1, 10).foldLeft(0)(_ + _)
    // 45
    1
    2
    (0 /: List.range(1, 10)) ( _ + _)
    // 45

    foldRight()

    1
    2
    (List.range(1, 10) :\ 0)(_ - _)
    // 5

责权让渡

迭代让位于高阶函数

用map等函数替换了迭代。这笔“交易”的得失很清楚:如果能够用高阶函数把希望执行的操作表达出来,语言将会把操作安排得更高效,甚至只要增加一行par修饰,就能够让操作并行化。

闭包(closure)

谓闭包,实际上是一种特殊的函数,它在暗地里绑定了函数内部引用的所有变量。换句话说,这种函数(或方法)把它引用的所有东西都放在一个上下文里“包”了起来。
这样说并不等于开发者应该抛开所有的责任,不去理解低层次抽象的来龙去脉。在很多情况下,我们使用一个抽象,比如Stream的时候,必须清楚可能产生的连带后果。很多开发者都没认识到,即使有了Java8的StreamAPI,他们仍然需要理解Fork/Join库的细节才能写出高性能的代码。当你掌握了背后的原理,才能把力量用在最正确的地方。

柯里化(currying)和函数的部分施用(partial application)

柯里化指的是从一个多参数函数变成一连串单参数函数的变换。

部分施用指通过提前代入一部分参数值,使一个多参数函数得以省略部分参数,从而转化为一个参数数目较少的函数。

柯里化和部分施用都是在我们提供部分参数值之后,产出可以凭余下参数实施调用的一个函数。不同的地方在于,函数柯里化的结果是返回链条中的下一个函数,而部分施用是把参数的取值绑定到用户在操作中提供的具体值上,因而产生一个“元数”(参数的数目)较少的函数。

递归

递归是以一种带点计算机科学味道的方式来对一组事物进行迭代,让事物的集合反复对自身调用同样的方法,使集合随着每次迭代不断缩小,同时要始终小心地保证退出条件的有效性。很多时候,我们的问题核心就是对一个不断变短的列表反复地做同一件事,把递归用在这样的场合,写出来的代码就容易理解。

Stream和作业顺序重排

从命令式风格转变为函数式风格还有一个潜在的好处,那就是运行时有能力在涉及效率的问题上替我们做决定。

在使用Java平台上的各种函数式方案的时候,我们必须保证传给filter()等函数的lambda块不存在副作用,否则可能导致无法预料的结果。允许运行时发挥其优化能力的做法,再次印证了我们关于交出控制权的观点:放弃对繁琐细节的掌控,关注问题域,而非关注问题域的实现。

函数式语言常见特性

记忆(memoization)

指的是在函数级别上对需要多次使用的值进行缓存的机制。
只有纯(pure)函数才可以适用缓存技术。纯函数是没有副作用的函数:它不引用其他值可变的类字段,除返回值之外不设置其他的变量,其结果完全由输入参数决定。

惰性求值(laziness)

缓求值(lazyevaluation)是函数式编程语言常见的一种特性,指尽可能地推迟求解表达式。缓求值的集合不会预先算好所有的元素,而是在用到的时候才落实下来,这样做有几个好处。第一,昂贵的运算只有到了绝对必要的时候才执行。第二,我们可以建立无限大的集合,只要一直接到请求,就一直送出元素。第三,按缓求值的方式来使用映射、筛选等函数式概念,可以产生更高效的代码。Java8以前的Java语言本身不支持缓求值,但平台上有一些框架和后继语言提供了这样的支持。

演化的语言

函数式编程语言和面向对象语言对待代码重用的方式不一样。面向对象语言喜欢大量地建立有很多操作的各种数据结构,函数式语言也有很多的操作,但对应的数据结构却很少。面向对象语言鼓励我们建立专门针对某个类的方法,我们从类的关系中发现重复出现的模式并加以重用。函数式语言的重用表现在函数的通用性上,它们鼓励在数据结构上使用各种共通的变换,并通过高阶函数来调整操作以满足具体事项的要求。

少量的数据结构搭配大量的操作

函数式的数据结构

函数式的异常处理

Either类

有了Either类,以在确保类型安全的前提下,视情况返回异常或者有效结果(但不会同时返回两者)。按照函数式编程的传统习惯,异常(如果有的话)置于Either类的左值上,正常结果则放在右值。

Option类

Option类表述了异常处理中较为简化的一种场景,它的取值要么是none,表示不存在有效值,要么是some,表示成功返回

模式与重用

模版方法(Template Method)模式

策略(Strategy Method)模式

享元(Flyweight)模式

工厂(Factory)模式和柯里化

现实应用

Java8

函数式的基础设施

架构

Web框架

数据库

多语言与多范式

参考

文章目录
  1. 1. 函数式编程的基本函数
    1. 1.1. 筛选(Filter)
    2. 1.2. 映射(map)
    3. 1.3. 折叠/化约(reduce)
  2. 2. 责权让渡
    1. 2.1. 迭代让位于高阶函数
    2. 2.2. 闭包(closure)
    3. 2.3. 柯里化(currying)和函数的部分施用(partial application)
    4. 2.4. 递归
    5. 2.5. Stream和作业顺序重排
  3. 3. 函数式语言常见特性
    1. 3.1. 记忆(memoization)
    2. 3.2. 惰性求值(laziness)
  4. 4. 演化的语言
    1. 4.1. 少量的数据结构搭配大量的操作
    2. 4.2. 函数式的数据结构
      1. 4.2.1. 函数式的异常处理
      2. 4.2.2. Either类
      3. 4.2.3. Option类
  5. 5. 模式与重用
    1. 5.1. 模版方法(Template Method)模式
    2. 5.2. 策略(Strategy Method)模式
    3. 5.3. 享元(Flyweight)模式
    4. 5.4. 工厂(Factory)模式和柯里化
  6. 6. 现实应用
    1. 6.1. Java8
    2. 6.2. 函数式的基础设施
      1. 6.2.1. 架构
      2. 6.2.2. Web框架
      3. 6.2.3. 数据库
  7. 7. 多语言与多范式
  8. 8. 参考