Instructor: James Riely
def map(name: String, contents: String) =
for w <- contents do
emit (w, 1)
def reduce(word: String, partialCounts: Iterator) =
var sum = 0
for pc <- partialCounts do
sum = sum + pc
emit (word, sum)
def sum (xs:List[Int], z:Int = 0) : Int = xs match
case Nil => z
case y::ys => sum (ys, z + y)
val xs = List(11,21,31)
sum (xs)
sum(11::21::31::Nil)
--> sum(11::21::31::Nil, 0)
--> sum(21::31::Nil, 11)
--> sum(31::Nil, 32)
--> sum(Nil, 63)
-->
-->
-->
--> 63 = (((0 + 11) + 21) + 31)
def sum (xs:List[Int], z:Int = 0) : Int = xs match
case Nil => z
case y::ys => y + sum (ys, z)
val xs = List(11,21,31)
sum (xs)
sum(11::21::31::Nil)
--> sum(11::21::31::Nil, 0)
--> 11 + sum(21::31::Nil, 0)
--> 11 + (21 + sum(31::Nil, 0))
--> 11 + (21 + (31 + sum(Nil, 0)))
--> 11 + (21 + (31 + 0))
--> 11 + (21 + 31)
--> 11 + 52
--> 63 = (11 + (21 + (31 + 0)))
def sum (xs:List[Int], z:Int) : Int =
xs match
case Nil => z
case y::ys => sum (ys, z + y)
val xs = List(11,21,31)
sum (xs, 0)
res1: Int = 63
def foldLeft (xs:List[Int], z:Int, f:((Int,Int)=>Int)) : Int =
xs match
case Nil => z
case y::ys => foldLeft (ys, f(z,y), f)
val xs = List(11,21,31)
foldLeft (xs, 0, _+_)
res1: Int = 63
def foldLeft (xs:List[Int], z:String, f:(String,Int)=>String) : String =
xs match
case Nil => z
case y::ys => foldLeft (ys, f(z, y), f)
val xs = List(11,21,31)
foldLeft (xs, "", _ + "0x%02x".format(_))
res1: String = 0x0b0x150x1f
def foldLeft (xs:List[List[Int]], z:Int, f:(Int,List[Int])=>Int) : Int =
xs match
case Nil => z
case y::ys => foldLeft (ys, f(z, y), f)
val xss = List(List(11,21,31),List(),List(41,51))
foldLeft (xss, 0, _ + _.length)
res1: Int = 5
def foldLeft [Z,X] (xs:List[X], z:Z, f:((Z,X)=>Z)) : Z =
xs match
case Nil => z
case y::ys => foldLeft (ys, f(z,y), f)
val xs = List(11,21,31)
foldLeft (xs, "!", (z:String,x:Int) => z + "0x%02x".format(x))
res1: String = !0x0b0x150x1f
def foldRight [X,Z] (xs:List[X], z:Z, f:((X,Z)=>Z)) : Z =
xs match
case Nil => z
case y::ys => f (y, foldRight (ys, z, f))
val xs = List(11,21,31)
foldRight (xs, "!", (x:Int,z:String) => "0x%02x".format(x) + z)
res1: String = 0x0b0x150x1f!
foldLeft
is tail recursive:
return foldLeft (ys, f(z, y))
f
to
the head and the accumulated result
foldRight
is recursive into an argument:
return f (y, foldRight (ys, z))
f
to
the head and result of recursion
List
class has fold
methods
xss.foldLeft (0) ((z,xs)=>z + xs.length)
foldLeft
function
foldLeft (xss, 0, (z,xs)=>z + xs.length)
xss.foldLeft(0)(f) == (0 /: xss)(f)
xss.foldRight(0)(f) == (xss :\ 0)(f)
def foldLeft [Z,X] (xs:List[X], z:Z, f:((Z,X)=>Z)) : Z = xs match
case Nil => z
case y::ys => foldLeft (ys, f(z,y), f)
def foldRight [X,Z] (xs:List[X], z:Z, f:((X,Z)=>Z)) : Z = xs match
case Nil => z
case y::ys => f (y, foldRight (ys, z, f))
val xs = List(a, b, c)
foldLeft (xs, z, f) === f( f( f(z,a),b),c) === (z /: xs)(f)
foldRight(xs, z, f) === f(a, f(b, f(c,z))) === (xs :\ z)(f)
(z /: xs)(f) (xs :\ z)(f)
f f
/ \ / \
f c a f
/ \ / \
f b b f
/ \ / \
z a c z
def sum (xs: List[Int]) = xs.foldLeft(0)(_+_)
def prod (xs: List[Int]) = xs.foldLeft(1)(_*_)
def or (xs: List[Boolean]) = xs.foldLeft(false)(_||_)
def and (xs: List[Boolean]) = xs.foldLeft(true)(_&&_)
def append [X] (xs: List[X])(ys: List[X]) = xs.foldRight(ys)(_::_)
def flatten [X] (xs: List[List[X]]) = xs.foldLeft(Nil:List[X])(_:::_)
def length [X] (xs: List[X]) = xs.foldLeft(0)((z,x)=>z+1)
def reverse [X] (xs: List[X]) = xs.foldRight(Nil:List[X])((x,zs)=>zs:::List(x))
def map [X,Y] (xs: List[X], f: X=>Y) = xs.foldRight(Nil:List[Y])(f(_)::_)
def filter [X] (xs: List[X], f: X=>Boolean) = xs.foldRight(Nil:List[X])((x,zs)=>if f(x) then x::zs else zs)
Here are lots and lots of foldleft examples