9. λ
表
达
式
Expr = Iden
| Iden => Expr
| (Expr) (Expr)
x, y, name, id, person
x => name, x => id, x => x
x(y), y(x), (x => name) y, (x => +(x)(1)) 3
x => y => +(x)(y)
10. λ
演
算
α 变换
Β 规约
η 变换
x => x == y => y, x => +(x)(z) == y => +(y)(z)
(x => +(x)(3)) 2 == +(2)(3)
(x => y => +(x)(y)) 2 3 == +(2)(3)
x => f(x) == f
11. 丘
奇
数
Zero = f => x => x
One = f => x => f(x)
Two = f => x => f(f(x))
Succ = n => f => x => f(n(f)(x))
type ChurchNumber[A] = (A => A) => A => A
def zero[A]: ChurchNumber[A] = f => a => a
def succ[A](n: ChurchNumber[A]): ChurchNumber[A] = f => a => f(n(f)(a))
val a1: Int = 0
val f1: Int => Int = x => x + 1
val a2: List[Int] = List()
val f2: List[Int] => List[Int] = list => 1 :: list
val a3: String = ""
val f3: String => String = s => "|" + s
println(zero(f1)(a1); println(succ(succ(zero))(f1)(a1)
Number = Zero
| Succ Number
12. type Segment = (List[Int], List[Int], List[Int])
object Split {
def unapply (xs: List[Int]) = {
val pivot = xs(xs.size / 2)
@tailrec
def partition (s: Segment, ys: List[Int]): Segment = {
val (left, mid, right) = s
ys match {
case Nil => s
case head :: tail if head < pivot => partition((head :: left, mid, right), tail)
case head :: tail if head == pivot => partition((left, head :: mid, right), tail)
case head :: tail if head > pivot => partition((left, mid, head :: right), tail)
}
}
Some(partition((Nil, Nil, Nil), xs))
}
}
def qsort(xs: List[Int]): List[Int] = xs match {
case Nil => xs
case Split(left, pivot, right) => qsort(left) ::: pivot ::: qsort(right)
}
Quick Sort
尾递归
Extractor
模式匹配
Guard
13. Pattern Matching
def sum(list: List[Int]): Int =
if (list.isEmpty) 0
else list.head + sum(list.tail)
def sum(list: List[Int]): Int = list match {
case List() => result
case head :: tail => head + sum(tail)
}
14. 尾递归
def sum(list: List[Int], acc: Int): Int = list match {
case Nil => result
case head :: tail => sum(tail, result + head)
}
15.
16. var list = (1 to 100).toArray
for (int i = 1; i <= 100; i++) {
list[i] += 1
}
list = list.map(1 +)
为
什
么
要
函
数
式
编
程
17. var list = (1 to 100).toArray
for (int i = 1; i <= 100; i++) {
list[i] += 1
}
list = list.view.map(1 +)
为
什
么
要
函
数
式
编
程
18. var list = (1 to 100).toArray
for (int i = 1; i <= 100; i++) {
list[i] += 1
}
list = list.par.map(1 +)
为
什
么
要
函
数
式
编
程
20. 5 + 3
柯里化
fold(z: Int)(f: (Int, Int) => Int): Int
val list = List(1, 2, 3, 4)
def fold0 = list.foldLeft(0)
def fold1 = list.foldLeft(1)
: Int
5 + : Int => Int
+ : (Int, Int) => Int
fold0((x, y) => x + y)
fold1((x, y) => x * y)
: ((Int, Int) => Int) => Int
: ((Int, Int) => Int) => Int
+ : Int => Int => Int
21. 副作用
class Pair[A](var x: A, var y: A) {
def modifyX(x: A) = this.x = x
def modifyY(y: A) = this.y = y
}
var pair = new Pair(1, 2)
var pair1 = new Pair(pair, pair)
var pair2 = new Pair(pair, new Pair(1, 2))
pair.modifyX(3)
值与址
24. map(f: T => U): A[U]
filter(f: T => Boolean): A[T]
flatMap(f: T => A[T]): A[T]
groupBy(f: T => K): A[(K, List[T])]
sortBy(f: T => K): A[T]
NEW
Count: Int
Force: A[T]
Reduce(f: (T, T) => T): T
Higher-Order Functions
T
r
a
n
f
o
r
m
a
t
i
o
n
A
c
t
i
o
n
25. A
B
Map
[A] -> (A -> B) -> [B]
高阶函数
List(1, 2, 3, 4).map(_.toString)
(A -> B) -> ([A] -> [B])
26. A
A
Filter
?
A
[A] -> (A -> Boolean) -> [A]
高阶函数
List(1, 2, 3, 4).filter(_ < 3)
(A -> Boolean) -> ([A] -> [A])
27. A
B
Fold
自然
元素
[A] -> B -> (B -> A -> B) -> [B]
高阶函数
val list = List(“one”, “two”, “three”)
list.foldLeft(0)((sum, str) => {
if (str.contains(“o”) sum + 1
else sum
})
B -> (B -> A -> B) -> ([A] -> [B])
35. 惰性求值
Lazy val x = 3 + 3
def number = {println("OK"); 3 + 3}
class LazyValue(expr: => Int) {
var evaluated: Boolean = false
var value: Int = -1
def get: Int = {
if (!evaluated) {
value = expr
evaluated = true
}
value
}
}
val lazyValue = new LazyValue(number)
println(lazyValue.get)
println(lazyValue.get)
Thinking in Java
Map可以用装饰器模式来实现
Call By Name
39. trait Runnable {
val capability: Int
def run = println(s"I can run $capability meters!!!")
}
trait Singer {
val name: String
def singMyName = println(s"$name is singing")
}
abstract class Bird(kind: String) {
def fly = println(s"flying of kind: $kind")
}
继承
40. class Nightingale extends Bird("Nightingale") with Singer with Runnable {
val capability = 20
val name = "poly"
}
val myTinyBird = new Nightingale
myTinyBird.fly
myTinyBird.singMyName
myTinyBird.run
class Coder(language: String) {
val capability = 10
val name = "Handemelindo"
def code = println(s"coding in $language")
}
val me = new Coder("Scala") with Runnable with Singer
me.code
me.singMyName
me.run
继承
42. 一些小伙伴
trait class Tree
case class Leaf(info: String) extends Tree
case class Node(left: Tree, right: Tree) extends Tree
def traverse(tree: Tree): Unit = {
tree match {
case Leaf(info) => println(info)
case Node(left, right) => {
traverse(left)
traverse(right)
}
}
}
val tree: Tree = new Node(new Node(new Leaf("1"), new Leaf("2")), new Leaf("3"))
traverse(tree)
Case Class与ADT
继承作为和类型
case class作为积类型
Tree = Leaf String
| Node Tree Tree
45. type Int :: *
type String :: *
type (Int => String) :: *
type List[Int] :: *
type List :: ?
type Function1 :: ??
做一些抽象练习吧
type List :: * => *
type function1 :: * => * => * Function1[-T, +R]
def id(x: Int) = x
type Id[A] = A
type id[A[_], B] = A[B]
def id(f: Int => Int, x: Int) = f(x)
46. type Pair[K[_], V[_]] = (K[A], V[A]) forSome { type A }
(* -> *) -> (* -> *) -> *
设想,我们的程序要返回结果:
(Set(x,x,x,x,x), List(x,x,x,x,x,x,x,x,x,x))
val pair: Pair[Set, List] = (Set(“42”), List(52))
val pair: Pair[Set, List] = (Set(42), List(52))
做一些抽象练习吧
48. trait Monoid[A]{
val zero: A
def append(x: A, y: A): A
}
object IntNum extends Monoid[Int] {
val zero = 0
def append(x: Int, y: Int) = x + y
}
object DoubleNum extends Monoid[Double] {
val zero = 0d
def append(x: Double, y: Double) = x + y
}
def sum[A](nums: List[A])(tc: Monoid[A]) =
nums.foldLeft(tc.zero)(tc.append)
sum(List(1, 2, 3, 5, 8, 13))(IntNum)
sum(List(3.14, 1.68, 2.72))(DoubleNum)
对态射进行抽象
49. trait Monoid[A]{
val zero: A
def append(x: A, y: A): A
}
object IntNum extends Monoid[Int] {
val zero = 0
def append(x: Int, y: Int) = x + y
}
object DoubleNum extends Monoid[Double] {
val zero = 0d
def append(x: Double, y: Double) = x + y
}
def sum[A](nums: List[A])(implicit tc: Monoid[A]) =
nums.foldLeft(tc.zero)(tc.append)
sum(List(1, 2, 3, 5, 8, 13))
sum(List(3.14, 1.68, 2.72))
implicit
implicit
Type Class
1.抽象分离
2.可组合
3.可覆盖
4.类型安全
val list = List(1,3,234,56,5346,34)
list.sorted sorted[B >: A](implicit ord: math.Ording[B])
Type Class
61. Future
Future可以将计算包裹起来,它代表的是未来的结果
Unit = List
val future1= Future(SomeProcess)
val future2 = Future(AnotherProcess)
for {
value1 <- future1.map(SomeTransformation)
value2 <- future2
} yield value1 + value2
一些常见Monad
62. for {
(name, date(year, _, day)) <- nameList
if name.length > 3
char <- name
} yield char -> s”$name-$day@$year”
Usage
nameList.flatMap {
case (name, date(year, _, day)) =>
if (name.length > 3) {
name.map { char =>
char -> s"$name-$day@$year"
}
} else Map()
case _ => Map()
}
val date = “””(ddd)-(dd)-(dd)”””.r
val nameList = Map(
“haskell” -> “1900-12-12”, “godel” -> “1906-04-28”,
“church” -> “1903-06-14”, “turing” -> “1912/06/23”
)
63. var map = Map[Char, String]()
var i = 0
val list = nameList.toArray
while (i < list.size) {
val name = list(i)._1
val theDate = list(i)._2
if (theDate.matches("dddd-dd-dd")) {
val parts = theDate.split("-")
val year = parts(0)
val day = parts(2)
val charArray = name.toCharArray
var j = 0
while (j < charArray.length) {
val char = charArray(j)
map += char -> (name + "-" + day + "2" + year)
j += 1
}
}
i += 1
}
71. map(f: T => U)
filter(f: T => Boolean)
flatMap(f: T => Seq[U])
sample(fraction: Float)
groupByKey()
reduceByKey(f: (V, V) => V)
mapValues(f: V => W)
NEW
Count()
Collect()
Reduce(f: (T, T) => T)
Lookup(k: K)
Save(path: String)
take(n: Int)
RDD
T
r
a
n
f
o
r
m
a
t
i
o
n
A
c
t
i
o
n
union()
join()
cogroup()
crossProduct
sort(c Comparator[K])
partitionBy(p: Partitioner[K])
72. [(K1, V1)] -> [(K2, [V2])] -> [(K2, V3)]
Word Count
lines = spark.textFile("hdfs://...")
words = lines.flatMap(_.split(“//s+”))
wordCounts = words.map((_, 1))
result = wordCounts.reduceByKey(_ + _)
result.save(“hdfs://…”)
RDD
81. MLlibSVM with SGD
LR with SGD or LBFGS
NB
各类决策树
随机森林
GBT
LabeledPoint(Double, Vector)
Classification
val data = sc.textFile(“….")
val parsedData = data.map { line =>
val parts = line.split(' ')
LabeledPoint(parts(0).toDouble, parts.tail.map(x => x.toDouble).toArray)
}
val numIterations = 20
val model = SVMWithSGD.train(parsedData, numIterations)
val labelAndPreds = parsedData.map { point =>
val prediction = model.predict(point.features)
(point.label, prediction)
}
val trainErr = labelAndPreds.filter(r => r._1 != r._2).count.toDouble / parsedData.count
82. MLlib
LabeledPoint(Double <- Vector)
RegressionLinear
Ridge
Lasso
Isotonic
val data = sc.textFile(“….")
val parsedData = data.map { line =>
val parts = line.split(',')
LabeledPoint(parts(0).toDouble, parts(1).split(' ').map(x => x.toDouble).toArray)
}
val numIterations = 20
val model = LinearRegressionWithSGD.train(parsedData, numIterations)
val valuesAndPreds = parsedData.map { point =>
val prediction = model.predict(point.features)
(point.label, prediction)
}
val MSE = valuesAndPreds.map{ case(v, p) =>
math.pow((v - p), 2)}.reduce(_ + _) / valuesAndPreds.count