![Page 1: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/1.jpg)
Scala中的函数式特征
ADC 2013
![Page 2: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/2.jpg)
关于我
• 王宏江,花名:宏江 • Blog:h1p://hongjiang.info • 经历: – Java : 10y+ – Scala : 2y+ – 十年工作经验,2009年加入阿里,曾在阿里巴巴中文站和laiwang.com担任架构师,现在中间件&稳定性平台部门
– Scala布道者 – 业余马拉松爱好者
![Page 3: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/3.jpg)
说明
• 内容 1) Scala中的函数式的特征
2) Scala类型系统中的函数式特征 • 交流:h1ps://github.com/CSUG/csug/
• 旺旺群: Scala交流和答疑: 94329267/sugsug
![Page 4: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/4.jpg)
函数式语言
纯函数式语言
Haskell Miranda
非纯函数式语言
静态类型 动态类型
ML OCaml Scala F# Lisp Scheme Erlang
Clean
![Page 5: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/5.jpg)
关于Scala语言
面向对象与函数式被看成一个硬币的两面,Scala试图将这两⾯面融合起来
![Page 6: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/6.jpg)
怎么理解这两种风格?
![Page 7: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/7.jpg)
命令式与函数式
在《程序设计语言—实践之路》一书中 将“面向对象”与“面向过程”都归类为“命令式”语言
![Page 8: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/8.jpg)
命令式与函数式
![Page 9: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/9.jpg)
命令式与函数式
• 图灵机/冯诺依曼体系 – 其运算可看做: – 通过修改内存来反映运算的结果。 – (用命令修改状态)
• Lambda演算(λ calculus)形式 – 连续运算(基于函数)得到结果
![Page 10: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/10.jpg)
• 函数式程序是跟值打交道的,而不是跟状态打交道的。它们的工具是表达式,而不是命令。
—《ML for the Working Programmer》
![Page 11: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/11.jpg)
值 vs 状态
![Page 12: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/12.jpg)
副作用(side effect)
![Page 13: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/13.jpg)
Scala的做法
• 同时支持val和var体现了scala的“平衡”也可以说是“圆滑”
• 鼓励使用val,但并不排斥var;实际编码中val占大多数。
![Page 14: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/14.jpg)
函数式是面向表达式的
![Page 15: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/15.jpg)
Scala中的表达式
• 1) 所有的表达式都有值
• 2) 除了赋值和函数调用表达式,内置的几个表达式只有:if,while,for,try,match
• 3) 块表达式{…}是基本表达式的组合,它的值是最后一个表达式的值。
![Page 16: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/16.jpg)
Scala中的表达式
• 一些表达式的值: 1) a=1; 2) while(a<100){print(a)} 3) if(a<2) 1;
• 赋值表达式、while表达式的值是Unit类型,它的值是唯一的: ()
• if表达式缺乏else的话,不符合条件则返回Unit类型的();即上面相当于:if(a<2) 1 else ()
![Page 17: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/17.jpg)
赋值语句的注意点:
不同于java: 1)while( (line = readLine() ) != null ) 不起作用,前边的 line = readLine() 得到的是Unit类型值
2)x=y=1; // y=1; x=() y=1表达式的结果是(),x被赋予了Unit类型的值
![Page 18: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/18.jpg)
表达式主要是由函数调用组成的
![Page 19: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/19.jpg)
Funcfon vs Method
![Page 20: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/20.jpg)
Scala中的Funcfon/Method/Functor
1) 狭义地区分(从可传递性上): 方法(method): 指的是在trait/class/object中以def关键字声明的,它不能被
直接传递。 函数(funcfon): 类型为ParamsType=>ResultType的变量,这些变量背后是
用FuncfonN对象来封装的;可以被传递。方法可以转换为函数。 2) 广义上,抛开背后的实现,方法就是函数;编译器某些场景自动把方
法封装为一个函数对象来传递。Scala社区并不特别区分这两个名词,注意语境,有时候函数就是指方法,有时候则是指函数对象
![Page 21: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/21.jpg)
函数作为一等公民
![Page 22: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/22.jpg)
函数作为一等公民体现在哪儿?
1) 可传递/赋值 2) 嵌套函数和匿名函数 3) 高阶 4) 偏应用(parfal applicafon) 5) 闭包
参考: h1p://en.wikipedia.org/wiki/First-‐class_funcfon
![Page 23: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/23.jpg)
可传递
scala> def hf(f: ()=>String) = println(f) hf: (f: () => String)Unit scala> hf(()=>“hi”) // 传递一个匿名函数 hi scala> def foo() = "ok" foo: ()String scala> hf(foo) // eta-‐conversion: ()=>foo() ok
![Page 24: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/24.jpg)
可传递
scala> val fun = (x:Int) => print(x) fun: Int => Unit = <funcfon1> scala> fun(2) 2
![Page 25: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/25.jpg)
嵌套函数
scala> def foo () { | def bar() { | println("hi") | } | bar | }
![Page 26: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/26.jpg)
嵌套函数
嵌套函数应用场景并不多,其中一个场景是 将递归函数的转为尾递归方式
![Page 27: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/27.jpg)
lambda: 函数字面量(Funcfon literal)
(x :Int, y: Int) => x + y
参数 函数体 右箭头
产生一段匿名函数,类型为 (Int,Int)=>Int Scala中参数的个数为0到22个。
匿名函数
![Page 28: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/28.jpg)
高阶函数
![Page 29: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/29.jpg)
Scala里的高阶函数
第一种:用函数做参数的函数。eg:
scala> def f2(f: ()=>Unit) { f() } f2: (f: () => Unit)Unit
scala> def f1() {println(1)} f1: ()Unit
scala> f2(f1) 1
scala> f2(()=>println(“hi”)) //传入匿名函数 hi
![Page 30: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/30.jpg)
Scala里的高阶函数
第二种:产生的结果是一个函数的函数。eg:
scala> def hf():Int=>Int = x=>x+1 hf: ()Int => Int
scala> val fun = hf fun: Int => Int = <funcfon1>
scala> fun(2) res0: Int = 3
![Page 31: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/31.jpg)
在lambda演算中,每个表达式都代表一个只有单独参数的函数,这个函数的参数本身也是一个只有单一参数的函数,同时,函数的值是又一个只有单一参数的函数。
![Page 32: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/32.jpg)
• 多个参数的函数怎么办?
![Page 33: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/33.jpg)
柯里化(currying)
![Page 34: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/34.jpg)
柯里化(currying)
scala> def sum(x:Int, y:Int) = x+y sum: (x: Int, y: Int)Int //参数打散,两个参数分开 scala> def sum2(x:Int)(y:Int) = x+y sum2: (x: Int)(y: Int)Int
![Page 35: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/35.jpg)
柯里化(currying)
scala> sum2(1)(2) res1: Int = 3 // 上面的调用相当于下面的几个步骤 scala> def first(x:Int) = (y:Int)=>x+y first: (x: Int)Int => Int scala> first(1) res2: Int => Int = <funcfon1> scala> val second = first(1) second: Int => Int = <funcfon1> scala> second(2) res3: Int = 3
![Page 36: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/36.jpg)
柯里化(currying)
• 函数链 把一个带有多个参数的函数,转换为多个只有一个参数的函数来执行 f(1)(2)(3) à ((f(1))(2))(3)
fa(1) r(2) fc(3)
产生新的函数
带入参数1执行
产生新的函数
x
得到最终的值
带入参数2执行 带入参数3执行
![Page 37: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/37.jpg)
柯里化(currying) • 柯理化的实际用途? 1) 控制抽象,可改变代码的书写风格。
foo(res, ()=>print(“test))
foo(res)(()=>print(“test”)) foo(res){ ()=>print(“test”) }
![Page 38: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/38.jpg)
柯里化(currying)
• 柯理化的实际用途? 2) 实现部分应用函数。
![Page 39: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/39.jpg)
部分应用函数(parfal applicafon funcfon)
把一个函数适配为另一个函数
![Page 40: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/40.jpg)
偏应用函数(parfal applicafon funcfon)
占位符:_ scala> def pow(x:Int, y:Int) = Math.pow(x,y) pow: (x: Int, y: Int)Double
scala> pow(2,3) res4: Double = 8.0
scala> val square = pow(_:Int, 2) square: Int => Double = <funcfon1>
scala> square(3) res5: Double = 9.0
![Page 41: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/41.jpg)
部分应用函数(parfal applicafon funcfon)
scala> def log(fme:Date, msg:String) { println(fme + ": " + msg) } log: (fme: java.ufl.Date, msg: String)Unit
scala> val log2 = log(new Date, _:String) log2: String => Unit = <funcfon1>
scala> log2("test1") scala> log2("test2") scala> log2("test3") 三次时间一样吗? 绑定的是表达式,还是表达式的结果?
![Page 42: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/42.jpg)
部分应用函数(parfal applicafon funcfon)
不绑定任何参数 scala> val pow2 = pow _ pow2: (Int, Int) => Double = <funcfon2>
![Page 43: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/43.jpg)
闭包(closure)
![Page 44: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/44.jpg)
Java中的匿名内部类如何访问局部变量
public Thread createThread(){ // 提升局部变量的生命周期
final int innerVar = 100; return new Thread(){ public void run(){ System.out.println(innerVar); } }; }
innerVar 还是分配在栈空间上么? Java的匿名内部类,和闭包很像。但用匿名内部类来实现,前提是先要定义好该行为的接口。繁琐一些,不那么灵活
![Page 45: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/45.jpg)
逻辑行为 + 上下文
![Page 46: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/46.jpg)
scala> def foo = { | val localVal = "hello" | val fun = ()=> localVal + ",world" | fun | }
![Page 47: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/47.jpg)
Scala的类型系统中的函数式特征
![Page 48: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/48.jpg)
generic types as first-‐class types
![Page 49: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/49.jpg)
generic types as first-‐class types
怎么理解?
![Page 50: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/50.jpg)
List[T] type parameter
type constructor
Java : class List<T> {} Scala: class List[T]
![Page 51: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/51.jpg)
List2[C[_]]
类型参数也是⼀一个类型构造器
Java : class List2<C<T>> {} //不支持 Scala: class List2[C[T]] 或
class List2[C[_]]
![Page 52: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/52.jpg)
scala> new List2[List]
generic types as first-‐class types
泛型也可以被当作类型参数传递,与普通类型没有区别
![Page 53: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/53.jpg)
type
Proper type(自身类型) Int, String, List[String] List2[List]
first-‐order/higher-‐order type (⼀一阶/⾼高阶类型: 类型构造器) List (一阶), List2 (高阶)
对类型归纳
![Page 54: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/54.jpg)
Higher-‐kinded type
![Page 55: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/55.jpg)
Kind ?
![Page 56: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/56.jpg)
类型是对数据的抽象
“hi” “alibaba” 2 100
String Int
![Page 57: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/57.jpg)
Kind: 类别,对类型的抽象
Types
Values
Kinds
注:“类别”这个翻译不确定是不是标准
![Page 58: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/58.jpg)
所有的proper type 被抽象为同一种 kind,用 * 表示
String List[Int]
*
Pair[Int,Int]
Kind:
Proper type:
![Page 59: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/59.jpg)
对一阶类型的抽象:
List
* → *
Pair
一阶Kind:
一阶类型/ 类型构造器: Set
* → * → *
通过Currying
![Page 60: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/60.jpg)
对⾼高阶类型的抽象:
List2
( * → *) → * Higher-‐Kind:
高阶类型/ 类型构造器:
![Page 61: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/61.jpg)
图上少了higher-‐kind , h1p://adriaanm.github.io/files/higher.pdf
![Page 62: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/62.jpg)
以函数的视角
class List[T] List是一个类型构造器,类似一个一阶函数,接受一个proper type参数,并生成一个proper type.
List : (T) => List[T] * → *
class List2[C[_]] List2类似高阶函数,接受一个类型构造器,生成一个proper type
List2: (T=>C[T]) => List2[C] (* → *) → *
![Page 63: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/63.jpg)
type lambda
Scala supports a limited version of type lambda
![Page 64: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/64.jpg)
type lambda
scala> def foo[M[_]] (f : M[Int]) = f scala> foo[List] ( List(1,2,3) ) res9: List[Int] = List(1, 2, 3) scala> foo ( List(1,2,3) ) // 类型参数可以省略,编译器会推断 res9: List[Int] = List(1, 2, 3) scala> foo( (x:Int) => println(x) ) // 如何让这句能编译通过?
![Page 65: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/65.jpg)
type lambda
(x:Int) => println(x) 背后是 Funcfon1[Int, Unit] scala> foo[ ({type X[Y] = Funcfon1[Y, Unit]})#X ] ( (x:Int)=>print(x) ) res5: Int => Unit = <funcfon1>
![Page 66: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/66.jpg)
Scala 的类型系统是图灵完备的,即利用类型系统本身就可以解决一些问题。
利用scala的类型系统解决汉诺塔: h1ps://gist.github.com/jrudolph/66925
![Page 67: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/67.jpg)
我们在招人
• 不限内部或外部
• 联系: hongjiang.wanghj@alibaba-‐inc.com
![Page 68: Scala中的函数式特征 - IT168topic.it168.com/factory/adc2013/doc/wanghongjiang.pdf · 函数(funcon):( 类型为ParamsType=>ResultType的变量,这些变量背后是 用FunconN](https://reader036.vdocuments.pub/reader036/viewer/2022081721/6020c277d15eed0dea45ac7b/html5/thumbnails/68.jpg)
Q&A