# Cs776(Prasad)L7fold1 Fold Operations Abstracting Repetitions.

## Presentation on theme: "Cs776(Prasad)L7fold1 Fold Operations Abstracting Repetitions."— Presentation transcript:

cs776(Prasad)L7fold2 Motivation : Appending lists lappend (link) –generalization of binary append to appending an arbitrary number of lists fun lappend [] = [] | lappend (s::ss) = s @ (lappend ss) lappend : ’ a list list -> ’ a list

cs776(Prasad)L7fold3 Properties (Identities) (map f) o lappend = lappend o (map (map f)) filter p (xs @ ys) = (filter p xs) @ (filter p ys) (filter p) o lappend = lappend o (map (filter p))

cs776(Prasad)L7fold4 Fold Operators Generalize binary operators to n-ary functions (list functions). Abstract specific patterns of recursion / looping constructs. Potential for optimization of special forms. foldl, accumulate, revfold, … foldr, reduce, fold, … foldl1 foldr1

cs776(Prasad)L7fold5 Foldr (SML97) foldr f a [x1,x2,…,xn] = f( x1, f(x2, …, f(xn,a)...)) fun foldr f a [] = a | foldr f a (x::xs) = f (x, foldr f a xs) foldr : ( ’ a* ’ b -> ’ b) -> ’ b -> ’ a list -> ’b foldr (op +) 10 [1,2,3] = 16

cs776(Prasad)L7fold6 Examples foldr (op +) a [x1,x2,x3] = ( x1 + ( x2 + ( x3 + a) ) ) ) foldr (op ::) [1,0] [4,3,2] = [4,3,2,1,0]

cs776(Prasad)L7fold7 (cont’d) fold in OldML ( not suited for partial eval.) fold : ( ’ a* ’ b -> ’ b) -> ’ a list -> ’ b -> ’ b foldr in Bird and Wadler (Curried func.) reduce in Reade foldr : ( ’ a -> ’ b -> ’ b) -> ’ b -> ’ a list -> ’ b

cs776(Prasad)L7fold8 Foldl (SML97) foldl f a [x1,x2,…,xn] = f(xn,f(…,f(x2,f(x1,a))…)) fun foldl f a [] = a | foldl f a (x::xs) = foldl f (f(x,a)) xs foldl : ( ’ a* ’ b -> ’ b) -> ’ b -> ’ a list -> ’ b foldl (op * ) 10 [1,2,3] = 60

cs776(Prasad)L7fold9 Examples foldl (op *) a [x1,x2,…,xn] = (xn * (…*(x2 * (x1 * a))...)) foldl (op @) [0] [[1],[2],[3],[4]] = [4,3,2,1,0] foldl (op ::) [1,0] [4,3,2] = [2,3,4,1,0]

cs776(Prasad)L7fold10 (cont’d) revfold in OldML ( not suited for partial eval.) revfold : ( ’ b* ’ a -> ’ b) -> ’ a list -> ’ b -> ’ b foldl in Bird and Wadler (Curried func.) accumulate in Reade foldl : ( ’ b -> ’ a -> ’ b) -> ’ b -> ’ a list -> ’ b

cs776(Prasad)L7fold11 Examples fun pack ds = foldl (fn (d,v)=> d+v*10) 0 ds pack [1,2,3,4] = 1234 fun packNot ds = foldl (fn (d,v)=> d*10+v) 0 ds packNot [1,2,3,4] = 100 fun packNott ds = foldr (fn (d,v)=> d+v*10) 0 ds packNott [1,2,3,4] = 4321

cs776(Prasad)L7fold12 fun myId lis = foldr (fn (x,xs) => x::xs) [] lis myId [1,2,3,4] = [1,2,3,4] fun myRev lis = foldl (fn (x,xs) => x::xs) [] lis myRev [1,2,3,4] = [4,3,2,1]

cs776(Prasad)L7fold13 fun filter p lis = foldr (fn (x,xs) => if p x then x::xs else xs) [] lis; filter (fn x => x = 2) [1,2,3,2] fun filterNeg p lis = foldl (fn (x,xs) => if p x then xs else xs@[x]) [] lis; filterNeg (fn x => true) [“a”,”b”,”a”]

cs776(Prasad)L7fold14 fun takewhile p lis = foldr (fn (x,xs) => if p x then x::xs else []) [] lis; takewhile (fn x => x = 2) [2,2,3,1,2] fun dropwhile p lis = foldl (fn (x,xs) => if null xs andalso p x then xs else xs@[x]) [] lis; dropwhile (fn x => true) [1,2,3]

cs776(Prasad)L7fold15 Generalizing Operators without identity element E.g., max, min, etc for which basis clause (for []) cannot be defined. foldl_1 fun foldl_1 f (x::xs) = foldl f x xs; foldr_1 fun foldr_1 f (x::[]) = x foldr_1 | foldr_1 f (x::y::ys) = foldr_1 f x (foldr_1 f (y::ys))

cs776(Prasad)L7fold16 Laws : Identities If f is a binary function that is associative and a is an identity w.r.t. f, then foldr f a xs = foldl f a (rev xs) foldr (op @) [] [[1,2],[3,4],[5]] = [1,2,3,4,5] foldl (op @) [] (rev [[1,2],[3,4],[5]]) = [1,2,3,4,5] foldl (op @) [] [[1,2],[3,4],[5]] = [5,3,4,1,2]

cs776(Prasad)L7fold17 Laws : Identities If f is a binary function that is commutative and a is an identity w.r.t. f, then foldr f a xs = foldl f a xs foldr (op * ) 1 [1,2,3] = 6 foldl (op * ) 1 [1,2,3] = 6 foldr (fn(b,v)=> b andalso v) true [false] = false foldl (fn(b,v)=> b andalso v) true [false] = false

cs776(Prasad)L7fold18 foldl (op +) 0 [1,2,3] = foldl (op +) 1 [2,3] = foldl (op +) 3 [3] = foldl (op +) 6 [] = 6 ( foldl : Efficient) (Tail Recursive) foldr (op +) 0 [1,2,3] =1+foldr (op +) 0 [2,3] =3 + foldr (op +) 0 [3] =6 + foldr (op +) 0 [] = 6 foldl and t [t,f,t] = foldl and t [f,t] = foldl and f [t] = foldl and f [] = false ( foldr : Efficient) (Short-circuit evaluation) foldr and t [t,f,t] = and t (foldr and t [f,t] = and f (foldr and t [t]) = false Comparing foldl and foldr.

cs776(Prasad)L7fold19 scan (processing prefixes) scan f a [x1,x2,…,xn] = [a,(f a x1),(f (f a x1) x2),…, (f … (f (f a x1) x2) …xn)] fun scan f a [] = [a] | scan f a xs = let val t = (scan f a (init xs)) in t @ [(f (last t) (last xs))] end;