狠狠撸

狠狠撸Share a Scribd company logo
Ihome In Action 函数式编程介绍 Author:Dennis —— IHOME 的今生来世之篇外篇
什么是 FP FP : Functional Programming 是指基于 lambda 演算的一种编程典范,函数式编程是一系列理念,而非教条。 Lambda 演算: 一套用于研究 函数 定义、函数应用和 递归 的 形式系统 。它由 丘奇 ( Alonzo Church )和他的学生 克莱尼 ( Stephen Cole Kleene )在 20 世纪 30 年代 引入
FP 的优点 Lambda 演算与图灵模型等价 无副作用: 1 、无锁,并行, Erlang 2 、利于单元测试 机器辅助的推理和优化  amb 操作符 Less Code  更高的抽象能力带来更少的代码,更优雅的实现。
FP 特性 无副作用、高阶函数、闭包、 currying 、延时求值、 Continuation 、模式匹配、 Mond……
无副作用 1 、所有符号都是 final ,利于单元测试和调试,只需要关心输入、输出 2 、从来不会有两个线程修改同一变量的情况出现,无需锁,无需临界区,利于并行, erlang 就是个例子 3 、由于函数无副作用,因此函数的组合也将是无副作用的,这在命令式语言是不可想象的
高阶函数 函数:在 scheme 中通常称为 procedure ,例子: +  =>  #<primitive:+>  (define (square x) (* x x) (square 3)  => 9 (square 4)  => 10 ( (lambda(x) (* x x))  3)  => 9  匿名函数 函数可以作为参数,作为返回值。 高阶函数: high-order function ,简而言之就是操作函数的函数。注意,在 FP 中,函数是 first-class
高阶函数例子 Map 、 foreach 、 filter 、 map, 将 proc 作用于列表的每个元素,返回新的列表: (define (map proc items) (if (null? Items) '() (cons (proc (car items)) (map proc (cdr items))))) (map square (list 1 2 3 4)) => (1 4 9 16)
高阶函数 filter 用于过滤列表,根据谓词predicate结果判断 (define (filter predicate sequence) (cond ((null? sequence) '()) ((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence)))) (else (filter predicate (cdr sequence)))))
高阶函数 accumulate 将列表中的元素按照操作OP累积起来 (define (accumulate op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence)))))
高阶函数 合并 合并起来,求解下列问题: 求解<=n中所有fib(k)是偶数的列表 第一步:生成0-n (define (enumerate-interval low high) (if (> low high) '() (cons low (enumerate-interval (+ low 1) high)))) (enumerate-interval 0 n)
高阶函数 合并 第二步:由map生成0-n整数对应的fib(k) (map fib (enumerate-interval 0 n)) 第三步:过滤偶数 (filter even?  (map fib (enumerate-interval 0 n)))
高阶函数 合并 第四步:将结果累积到列表 (accumulate cons '() (filter even? (map (enumerate-interval 0 n)))))
高阶函数 合并 最终结果: (define (even-fibs n) (accumulate cons  '() (filter even?  (map fib (enumerate-interval 0 n)))))
高阶函数 合并 以信息流的方式去观察,高阶函数带来了约定接口的抽象
闭包 - 定义 严格定义:闭包是包含了自由变量的代码块  泛化:匿名函数, block 都归入闭包 自由变量? (define (get-adder x) (lambda(y)(+ x y))) X 就是自由变量,在离开 get-adder 作用域之后仍然可以访问。 (define add4 (get-adder 4)) (add4 7)  => 11 闭包作用:模块化、简化代码、抽象
闭包 - 应用举例 排序: Java: class Product implements Comparator{ public int compare(Product other) return this.price-other.price … Collections.sort(products) Ruby: products.sort{|a,b| a.price-b.price}
闭包 - 应用举例 Java7 引入的闭包语法: double log = { double x => Math.log(x) }.invoke(10);  int sum = { int x, int y => x + y }.invoke(3, 4); // will return 7  String[] girls = { &quot;Jane&quot;, &quot;Eva&quot;, &quot;Sarah&quot;, &quot;Alice&quot; }; Arrays.sort(girls, { String s1, String s2 => int r = s1.length() - s2.length(); r == 0 ? s1.compareTo(s2) : r });
闭包应用举例 模拟对象, lua: function make_stack() ???????  local data = {}; ??????? local last = -1; ???????  local function push(e) ??????????? last = last + 1; ??????????? data[last] = e; ??????? end ???????  local function pop() ??????????? if last == -1 then ??????????????? return nil ??????????? end ??????????? last = last - 1 ??????????? return data[last+1] ??????? end ???????  return function (index) ??????????? local tb = {push=push, pop=pop} ??????????? return tb[index] ??????? end end s=make_stack() s(&quot;push&quot;)(&quot;test0&quot;) s(&quot;push&quot;)(&quot;test1&quot;) s(&quot;push&quot;)(&quot;test2&quot;) s(&quot;push&quot;)(&quot;test3&quot;) print(s(&quot;pop&quot;)()) print(s(&quot;pop&quot;)()) print(s(&quot;pop&quot;)())
Currying Currying :俗称克里化,命名为了纪念逻辑学家 Haskell Curry 。它是为了解决 lambda 演算在多个参数情况下而引入的。作用是把带有多个参数的函数转化为带有单个参数的函数(其余的参数由 curry 来决定如何处理)
Currying 例子 1 Javascript 为例: function?add(x,?y)?   {??  ????if(x!=null?&&?y!=null)?return?x?+?y;?? ???? else?if(x!=null?&&?y==null)? return?function(y)? {??  ?????????return?x?+?y;?  ????  }? ???? else?if(x==null?&&?y!=null) ? return?function(x)?{??  ????????return?x?+?y;?  ????}?  }? var?a?=?add(3,?4);? var?b?=?add(2);? var?c?=?b(10);?
Currying 例子 2 Ruby1.9 引入了 Proc#curry plus?=?lambda?{|a,b|?a?+?b}??  plus(3,4)  =>7 curried_plus?=?plus.curry  plus_three?=?curried_plus[3]?  plus_three(4)  =>7
Currying 例子 3 可以写出很优雅的代码 is_weekday?=?lambda?{|day_of_week,?time|?time.wday?==?day_of_week}.curry?? ?? sunday????=?is_weekday[0]?? monday????=?is_weekday[1]?? tuesday???=?is_weekday[2]?? wednesday?=?is_weekday[3]?? thursday??=?is_weekday[4]?? friday????=?is_weekday[5]?? saturday??=?is_weekday[6]?? ?? case?Time.now?? when?sunday??? ?? puts?&quot;Day?of?rest&quot;?? when?monday,?tuesday,?wednesday,?thursday,?friday?? ?? puts?&quot;Work&quot;?? when?saturday?? ?? puts?&quot;chores&quot;?? end??
延时求值 Lazy evalution :函数调用时,对参数的求值推迟到需要使用该参数的时候。 作用: 1 、特殊的控制结构 2 、无穷列表,流 (stream)
特殊的控制结构 Unless过程: (define (unless condition usual-value exception-value) (if condition Exception-value Usual-value)) (unless (= 0 0) (/ 1 0) (begin (display “exception return 0”) 0))
特殊的控制结构 这个函数在非延时求值器的时候将无法正确求值,因为(/ 1 0)在函数调用前将求值,抛出错误。 而在一个延时求值器中,由于推迟了对参数的求值,那么在(= 0 0)返回true之后,直接求值exception-value并返回,(/ 1 0)将根本不会被调用到,从而整个函数可以正确运作。
无穷级数 相对于cons、car、cdr,我们定义相应的stream-cons stream-car stream-cdr,因此也有相应的高阶函数stream-map stream-filter等。 定义自然数:  (define (integers-starting-from n) (cons-stream n (integers-starting-from (+ n  1)))) (define integers (integers-starting-from 1))
无穷级数 定义1的无穷数列 (define ones (cons-stream 1 ones)) 更无敌的例子,筛法求素数的无穷数列:
筛法求素数 (define (divisible? x y) (= (remainder x y) 0)) (define (sieve stream) (cons-stream (stream-car stream) (sieve (stream-filter (lambda(x) (not (divisible? x (stream-car stream)))) (stream-cdr stream))))) (define primes (sieve (integers-starting-from 2)))
Continuation 表达式的求值分为两个阶段: 1 、 what to evalute? 2 、 waht to do with the value? 那么 what to do with the value 就称为表达式的延续 (continuation)
Continuation 例子 (if (null? x) '() (cdr x)) 表达式(null? x)求值后,根据这个表达式的值去决定执行'()还是(cdr x),这个决定的过程就是表达式(null? x)的延续. (+ 2 (call/cc (lambda (k) (* 5 (k 4)))))  => 6
Continuation 在语言中的支持 call/cc:  call-with-current-continuation 该过程调用一个函数,并向此函数传入当前的continuation Scheme、Ruby中都有这个call/cc支持 Continuaton的作用: 1、实现高级的控制结构,break、goto 2、实现代码级别的程序调用,协程 3、实现机器推理所需要的fail、try机制
Continuation break 语句 scheme中是没有break的,可以通过continuation模拟: (define product (lambda (ls) (call/cc (lambda (break) (let f ((ls ls)) (cond ((null? ls) 1) ((= (car ls) 0) (break 0)) (else (* (car ls) (f (cdr ls))))))))))
Continuation amb 操作符 amb, 是 John McCarthy 在 1961 年提出的。 Amb 表达式 ( amb e1 e2 e3 e4 ...) 有歧义性地返回 n 个表达式中 ei 之一的值,例如: (list (amb 1 2 3) (amb 'a 'b)) 将有如下六个值: (1 a) (1 b)  (2 a) (2 b)  (3 a) (3 b) 注意: (amb) 永远是 fail 。 (define (require p) (if (not p) (amb)))
amb操作符的实现 通过call/cc实现,amb本质上是一种失败、回溯机制,通过continuation记录堆栈的跳转来实现 scheme的实现,通过宏 continuation 2.scm Ruby的实现  continuation.rb
amb操作符的使用 一道逻辑题: Baker, Cooper, Fletcher, Miller, 和Smith住在一动5层公寓的不同楼层。Baker不在顶楼住。Cooper不在底楼住。Fletcher既不在顶楼也不在底楼。Miller住的楼层比Cooper住的高。Smith和Fletcher的楼层不相邻。Fletcher和Cooper的楼层不相邻。问每个人住的楼层。
模式匹配

More Related Content

What's hot (20)

Java 開發者的函數式程式設計
Java 開發者的函數式程式設計Java 開發者的函數式程式設計
Java 開發者的函數式程式設計
Justin Lin
?
P127 135 new
P127 135 newP127 135 new
P127 135 new
hungchiayang1
?
Ppt 120-126
Ppt 120-126Ppt 120-126
Ppt 120-126
hungchiayang1
?
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
Wang Yizhe
?
尝补尘产诲补演算与邱奇编码
尝补尘产诲补演算与邱奇编码尝补尘产诲补演算与邱奇编码
尝补尘产诲补演算与邱奇编码
Qin Jian
?
Polar example
Polar examplePolar example
Polar example
Alisha Smile
?
Taylor example
Taylor exampleTaylor example
Taylor example
Alisha Smile
?
Ch10 範例
Ch10 範例Ch10 範例
Ch10 範例
hungchiayang1
?
Ppt 1-50
Ppt 1-50Ppt 1-50
Ppt 1-50
hungchiayang1
?
Python speed up with numba
Python speed up with numbaPython speed up with numba
Python speed up with numba
Jiang Wu
?
Ch12 範例
Ch12 範例Ch12 範例
Ch12 範例
hungchiayang1
?
Ppt 1-25
Ppt 1-25Ppt 1-25
Ppt 1-25
hungchiayang1
?
Ppt 136-140
Ppt 136-140Ppt 136-140
Ppt 136-140
hungchiayang1
?
Ppt 26-50
Ppt 26-50Ppt 26-50
Ppt 26-50
hungchiayang1
?
Ch9 範例
Ch9 範例Ch9 範例
Ch9 範例
hungchiayang1
?
Appendix A 教學
Appendix A 教學Appendix A 教學
Appendix A 教學
hungchiayang1
?
Ppt 78-100
Ppt 78-100Ppt 78-100
Ppt 78-100
hungchiayang1
?
Ch1 教學
Ch1 教學Ch1 教學
Ch1 教學
hungchiayang1
?
第2章符 号 运 算
第2章符 号 运 算第2章符 号 运 算
第2章符 号 运 算
eterou
?

Viewers also liked (18)

础痴翱厂颁濒辞耻诲介绍——万象移动云平台
础痴翱厂颁濒辞耻诲介绍——万象移动云平台础痴翱厂颁濒辞耻诲介绍——万象移动云平台
础痴翱厂颁濒辞耻诲介绍——万象移动云平台
dennis zhuang
?
闯补惫补多线程常见陷阱
闯补惫补多线程常见陷阱闯补惫补多线程常见陷阱
闯补惫补多线程常见陷阱
dennis zhuang
?
点评新架构
点评新架构点评新架构
点评新架构
dennis zhuang
?
贰谤濒补苍驳介绍
贰谤濒补苍驳介绍贰谤濒补苍驳介绍
贰谤濒补苍驳介绍
dennis zhuang
?
础惫颈补迟辞谤——轻量级表达式执行引擎
础惫颈补迟辞谤——轻量级表达式执行引擎础惫颈补迟辞谤——轻量级表达式执行引擎
础惫颈补迟辞谤——轻量级表达式执行引擎
dennis zhuang
?
CQL 实现
CQL 实现CQL 实现
CQL 实现
dennis zhuang
?
颁濒辞箩耻谤别的魅力
颁濒辞箩耻谤别的魅力颁濒辞箩耻谤别的魅力
颁濒辞箩耻谤别的魅力
dennis zhuang
?
颁濒辞箩耻谤别概览
颁濒辞箩耻谤别概览颁濒辞箩耻谤别概览
颁濒辞箩耻谤别概览
dennis zhuang
?
QCon - 一次 Clojure Web 编程实战
QCon - 一次 Clojure Web 编程实战QCon - 一次 Clojure Web 编程实战
QCon - 一次 Clojure Web 编程实战
dennis zhuang
?
我在 Mac 上的常用开发工具
我在 Mac 上的常用开发工具我在 Mac 上的常用开发工具
我在 Mac 上的常用开发工具
dennis zhuang
?
Clojure 1.8 Direct-Linking WWH
Clojure 1.8  Direct-Linking  WWHClojure 1.8  Direct-Linking  WWH
Clojure 1.8 Direct-Linking WWH
dennis zhuang
?
Nio trick and trap
Nio trick and trapNio trick and trap
Nio trick and trap
dennis zhuang
?
Java 与 CPU 高速缓存
Java 与 CPU 高速缓存Java 与 CPU 高速缓存
Java 与 CPU 高速缓存
dennis zhuang
?
Mesos intro
Mesos introMesos intro
Mesos intro
dennis zhuang
?
Elixir introd
Elixir introdElixir introd
Elixir introd
dennis zhuang
?
Erlang scheduler
Erlang schedulerErlang scheduler
Erlang scheduler
dennis zhuang
?
Hystrix 介绍
Hystrix 介绍Hystrix 介绍
Hystrix 介绍
dennis zhuang
?
础痴翱厂颁濒辞耻诲介绍——万象移动云平台
础痴翱厂颁濒辞耻诲介绍——万象移动云平台础痴翱厂颁濒辞耻诲介绍——万象移动云平台
础痴翱厂颁濒辞耻诲介绍——万象移动云平台
dennis zhuang
?
闯补惫补多线程常见陷阱
闯补惫补多线程常见陷阱闯补惫补多线程常见陷阱
闯补惫补多线程常见陷阱
dennis zhuang
?
贰谤濒补苍驳介绍
贰谤濒补苍驳介绍贰谤濒补苍驳介绍
贰谤濒补苍驳介绍
dennis zhuang
?
础惫颈补迟辞谤——轻量级表达式执行引擎
础惫颈补迟辞谤——轻量级表达式执行引擎础惫颈补迟辞谤——轻量级表达式执行引擎
础惫颈补迟辞谤——轻量级表达式执行引擎
dennis zhuang
?
颁濒辞箩耻谤别的魅力
颁濒辞箩耻谤别的魅力颁濒辞箩耻谤别的魅力
颁濒辞箩耻谤别的魅力
dennis zhuang
?
颁濒辞箩耻谤别概览
颁濒辞箩耻谤别概览颁濒辞箩耻谤别概览
颁濒辞箩耻谤别概览
dennis zhuang
?
QCon - 一次 Clojure Web 编程实战
QCon - 一次 Clojure Web 编程实战QCon - 一次 Clojure Web 编程实战
QCon - 一次 Clojure Web 编程实战
dennis zhuang
?
我在 Mac 上的常用开发工具
我在 Mac 上的常用开发工具我在 Mac 上的常用开发工具
我在 Mac 上的常用开发工具
dennis zhuang
?
Clojure 1.8 Direct-Linking WWH
Clojure 1.8  Direct-Linking  WWHClojure 1.8  Direct-Linking  WWH
Clojure 1.8 Direct-Linking WWH
dennis zhuang
?
Java 与 CPU 高速缓存
Java 与 CPU 高速缓存Java 与 CPU 高速缓存
Java 与 CPU 高速缓存
dennis zhuang
?

Similar to Ihome inaction 篇外篇之fp介绍 (20)

Hi Haskell
Hi HaskellHi Haskell
Hi Haskell
Jifeng Deng
?
算法基础报告
算法基础报告算法基础报告
算法基础报告
monicar201101
?
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
?
Ch5 教學
Ch5 教學Ch5 教學
Ch5 教學
hungchiayang1
?
functional-scala
functional-scalafunctional-scala
functional-scala
wang hongjiang
?
Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)
JIANG MING-LI
?
Scala+RDD
Scala+RDDScala+RDD
Scala+RDD
Yuanhang Wang
?
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Justin Lin
?
Bash shell script 教學
Bash shell script 教學Bash shell script 教學
Bash shell script 教學
Ming-Sian Lin
?
颁程式-函式与巨集
颁程式-函式与巨集颁程式-函式与巨集
颁程式-函式与巨集
艾鍗科技
?
Scala+spark 2nd
Scala+spark 2ndScala+spark 2nd
Scala+spark 2nd
Yuanhang Wang
?
Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18
Derek Lee
?
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
?
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
NCU MCL
?
Lua 30+ Programming Skills and 20+ Optimization Tips
Lua 30+ Programming Skills and 20+ Optimization TipsLua 30+ Programming Skills and 20+ Optimization Tips
Lua 30+ Programming Skills and 20+ Optimization Tips
Ho Kim
?
实验一 Mathematica软件介绍
实验一   Mathematica软件介绍实验一   Mathematica软件介绍
实验一 Mathematica软件介绍
guestfe33f0e
?
实验一 Mathematica软件介绍
实验一   Mathematica软件介绍实验一   Mathematica软件介绍
实验一 Mathematica软件介绍
Xin Zheng
?
香港六合彩
香港六合彩香港六合彩
香港六合彩
香港六合彩 香港六合彩
?
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
?
Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)
JIANG MING-LI
?
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Justin Lin
?
Bash shell script 教學
Bash shell script 教學Bash shell script 教學
Bash shell script 教學
Ming-Sian Lin
?
颁程式-函式与巨集
颁程式-函式与巨集颁程式-函式与巨集
颁程式-函式与巨集
艾鍗科技
?
Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18
Derek Lee
?
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
?
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
苍肠耻尘补冲厂测尘笔测符号运算套件.辫辫迟虫
NCU MCL
?
Lua 30+ Programming Skills and 20+ Optimization Tips
Lua 30+ Programming Skills and 20+ Optimization TipsLua 30+ Programming Skills and 20+ Optimization Tips
Lua 30+ Programming Skills and 20+ Optimization Tips
Ho Kim
?
实验一 Mathematica软件介绍
实验一   Mathematica软件介绍实验一   Mathematica软件介绍
实验一 Mathematica软件介绍
guestfe33f0e
?
实验一 Mathematica软件介绍
实验一   Mathematica软件介绍实验一   Mathematica软件介绍
实验一 Mathematica软件介绍
Xin Zheng
?

Ihome inaction 篇外篇之fp介绍

  • 1. Ihome In Action 函数式编程介绍 Author:Dennis —— IHOME 的今生来世之篇外篇
  • 2. 什么是 FP FP : Functional Programming 是指基于 lambda 演算的一种编程典范,函数式编程是一系列理念,而非教条。 Lambda 演算: 一套用于研究 函数 定义、函数应用和 递归 的 形式系统 。它由 丘奇 ( Alonzo Church )和他的学生 克莱尼 ( Stephen Cole Kleene )在 20 世纪 30 年代 引入
  • 3. FP 的优点 Lambda 演算与图灵模型等价 无副作用: 1 、无锁,并行, Erlang 2 、利于单元测试 机器辅助的推理和优化 amb 操作符 Less Code 更高的抽象能力带来更少的代码,更优雅的实现。
  • 4. FP 特性 无副作用、高阶函数、闭包、 currying 、延时求值、 Continuation 、模式匹配、 Mond……
  • 5. 无副作用 1 、所有符号都是 final ,利于单元测试和调试,只需要关心输入、输出 2 、从来不会有两个线程修改同一变量的情况出现,无需锁,无需临界区,利于并行, erlang 就是个例子 3 、由于函数无副作用,因此函数的组合也将是无副作用的,这在命令式语言是不可想象的
  • 6. 高阶函数 函数:在 scheme 中通常称为 procedure ,例子: + => #<primitive:+> (define (square x) (* x x) (square 3) => 9 (square 4) => 10 ( (lambda(x) (* x x)) 3) => 9 匿名函数 函数可以作为参数,作为返回值。 高阶函数: high-order function ,简而言之就是操作函数的函数。注意,在 FP 中,函数是 first-class
  • 7. 高阶函数例子 Map 、 foreach 、 filter 、 map, 将 proc 作用于列表的每个元素,返回新的列表: (define (map proc items) (if (null? Items) '() (cons (proc (car items)) (map proc (cdr items))))) (map square (list 1 2 3 4)) => (1 4 9 16)
  • 8. 高阶函数 filter 用于过滤列表,根据谓词predicate结果判断 (define (filter predicate sequence) (cond ((null? sequence) '()) ((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence)))) (else (filter predicate (cdr sequence)))))
  • 9. 高阶函数 accumulate 将列表中的元素按照操作OP累积起来 (define (accumulate op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence)))))
  • 10. 高阶函数 合并 合并起来,求解下列问题: 求解<=n中所有fib(k)是偶数的列表 第一步:生成0-n (define (enumerate-interval low high) (if (> low high) '() (cons low (enumerate-interval (+ low 1) high)))) (enumerate-interval 0 n)
  • 11. 高阶函数 合并 第二步:由map生成0-n整数对应的fib(k) (map fib (enumerate-interval 0 n)) 第三步:过滤偶数 (filter even? (map fib (enumerate-interval 0 n)))
  • 12. 高阶函数 合并 第四步:将结果累积到列表 (accumulate cons '() (filter even? (map (enumerate-interval 0 n)))))
  • 13. 高阶函数 合并 最终结果: (define (even-fibs n) (accumulate cons '() (filter even? (map fib (enumerate-interval 0 n)))))
  • 15. 闭包 - 定义 严格定义:闭包是包含了自由变量的代码块 泛化:匿名函数, block 都归入闭包 自由变量? (define (get-adder x) (lambda(y)(+ x y))) X 就是自由变量,在离开 get-adder 作用域之后仍然可以访问。 (define add4 (get-adder 4)) (add4 7) => 11 闭包作用:模块化、简化代码、抽象
  • 16. 闭包 - 应用举例 排序: Java: class Product implements Comparator{ public int compare(Product other) return this.price-other.price … Collections.sort(products) Ruby: products.sort{|a,b| a.price-b.price}
  • 17. 闭包 - 应用举例 Java7 引入的闭包语法: double log = { double x => Math.log(x) }.invoke(10); int sum = { int x, int y => x + y }.invoke(3, 4); // will return 7 String[] girls = { &quot;Jane&quot;, &quot;Eva&quot;, &quot;Sarah&quot;, &quot;Alice&quot; }; Arrays.sort(girls, { String s1, String s2 => int r = s1.length() - s2.length(); r == 0 ? s1.compareTo(s2) : r });
  • 18. 闭包应用举例 模拟对象, lua: function make_stack() ??????? local data = {}; ??????? local last = -1; ??????? local function push(e) ??????????? last = last + 1; ??????????? data[last] = e; ??????? end ??????? local function pop() ??????????? if last == -1 then ??????????????? return nil ??????????? end ??????????? last = last - 1 ??????????? return data[last+1] ??????? end ??????? return function (index) ??????????? local tb = {push=push, pop=pop} ??????????? return tb[index] ??????? end end s=make_stack() s(&quot;push&quot;)(&quot;test0&quot;) s(&quot;push&quot;)(&quot;test1&quot;) s(&quot;push&quot;)(&quot;test2&quot;) s(&quot;push&quot;)(&quot;test3&quot;) print(s(&quot;pop&quot;)()) print(s(&quot;pop&quot;)()) print(s(&quot;pop&quot;)())
  • 19. Currying Currying :俗称克里化,命名为了纪念逻辑学家 Haskell Curry 。它是为了解决 lambda 演算在多个参数情况下而引入的。作用是把带有多个参数的函数转化为带有单个参数的函数(其余的参数由 curry 来决定如何处理)
  • 20. Currying 例子 1 Javascript 为例: function?add(x,?y)? {?? ????if(x!=null?&&?y!=null)?return?x?+?y;?? ???? else?if(x!=null?&&?y==null)? return?function(y)? {?? ?????????return?x?+?y;? ???? }? ???? else?if(x==null?&&?y!=null) ? return?function(x)?{?? ????????return?x?+?y;? ????}? }? var?a?=?add(3,?4);? var?b?=?add(2);? var?c?=?b(10);?
  • 21. Currying 例子 2 Ruby1.9 引入了 Proc#curry plus?=?lambda?{|a,b|?a?+?b}?? plus(3,4) =>7 curried_plus?=?plus.curry plus_three?=?curried_plus[3]? plus_three(4) =>7
  • 22. Currying 例子 3 可以写出很优雅的代码 is_weekday?=?lambda?{|day_of_week,?time|?time.wday?==?day_of_week}.curry?? ?? sunday????=?is_weekday[0]?? monday????=?is_weekday[1]?? tuesday???=?is_weekday[2]?? wednesday?=?is_weekday[3]?? thursday??=?is_weekday[4]?? friday????=?is_weekday[5]?? saturday??=?is_weekday[6]?? ?? case?Time.now?? when?sunday??? ?? puts?&quot;Day?of?rest&quot;?? when?monday,?tuesday,?wednesday,?thursday,?friday?? ?? puts?&quot;Work&quot;?? when?saturday?? ?? puts?&quot;chores&quot;?? end??
  • 23. 延时求值 Lazy evalution :函数调用时,对参数的求值推迟到需要使用该参数的时候。 作用: 1 、特殊的控制结构 2 、无穷列表,流 (stream)
  • 24. 特殊的控制结构 Unless过程: (define (unless condition usual-value exception-value) (if condition Exception-value Usual-value)) (unless (= 0 0) (/ 1 0) (begin (display “exception return 0”) 0))
  • 25. 特殊的控制结构 这个函数在非延时求值器的时候将无法正确求值,因为(/ 1 0)在函数调用前将求值,抛出错误。 而在一个延时求值器中,由于推迟了对参数的求值,那么在(= 0 0)返回true之后,直接求值exception-value并返回,(/ 1 0)将根本不会被调用到,从而整个函数可以正确运作。
  • 26. 无穷级数 相对于cons、car、cdr,我们定义相应的stream-cons stream-car stream-cdr,因此也有相应的高阶函数stream-map stream-filter等。 定义自然数: (define (integers-starting-from n) (cons-stream n (integers-starting-from (+ n 1)))) (define integers (integers-starting-from 1))
  • 27. 无穷级数 定义1的无穷数列 (define ones (cons-stream 1 ones)) 更无敌的例子,筛法求素数的无穷数列:
  • 28. 筛法求素数 (define (divisible? x y) (= (remainder x y) 0)) (define (sieve stream) (cons-stream (stream-car stream) (sieve (stream-filter (lambda(x) (not (divisible? x (stream-car stream)))) (stream-cdr stream))))) (define primes (sieve (integers-starting-from 2)))
  • 29. Continuation 表达式的求值分为两个阶段: 1 、 what to evalute? 2 、 waht to do with the value? 那么 what to do with the value 就称为表达式的延续 (continuation)
  • 30. Continuation 例子 (if (null? x) '() (cdr x)) 表达式(null? x)求值后,根据这个表达式的值去决定执行'()还是(cdr x),这个决定的过程就是表达式(null? x)的延续. (+ 2 (call/cc (lambda (k) (* 5 (k 4))))) => 6
  • 31. Continuation 在语言中的支持 call/cc: call-with-current-continuation 该过程调用一个函数,并向此函数传入当前的continuation Scheme、Ruby中都有这个call/cc支持 Continuaton的作用: 1、实现高级的控制结构,break、goto 2、实现代码级别的程序调用,协程 3、实现机器推理所需要的fail、try机制
  • 32. Continuation break 语句 scheme中是没有break的,可以通过continuation模拟: (define product (lambda (ls) (call/cc (lambda (break) (let f ((ls ls)) (cond ((null? ls) 1) ((= (car ls) 0) (break 0)) (else (* (car ls) (f (cdr ls))))))))))
  • 33. Continuation amb 操作符 amb, 是 John McCarthy 在 1961 年提出的。 Amb 表达式 ( amb e1 e2 e3 e4 ...) 有歧义性地返回 n 个表达式中 ei 之一的值,例如: (list (amb 1 2 3) (amb 'a 'b)) 将有如下六个值: (1 a) (1 b) (2 a) (2 b) (3 a) (3 b) 注意: (amb) 永远是 fail 。 (define (require p) (if (not p) (amb)))
  • 35. amb操作符的使用 一道逻辑题: Baker, Cooper, Fletcher, Miller, 和Smith住在一动5层公寓的不同楼层。Baker不在顶楼住。Cooper不在底楼住。Fletcher既不在顶楼也不在底楼。Miller住的楼层比Cooper住的高。Smith和Fletcher的楼层不相邻。Fletcher和Cooper的楼层不相邻。问每个人住的楼层。