Midterm 2011 define maketree λ value children λ sel sel value children define rootvalue λ tree tree λ value children value ID: 275617
Download Presentation The PPT/PDF document "PPL Sequence Interface" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
PPL
Sequence InterfaceSlide2Slide3
Midterm 2011Slide4Slide5
(define make-tree
(
λ (
value children)
(
λ (
sel
)
(
sel
value children))))
(define root-value
(
λ (
tree)
(tree (
λ (
value children)
(value)))))
(define tree-children
(
λ (
tree)
(tree (
λ (
value children)
(children)))))Slide6
The Sequence Interface
Consider the following Java code:
int
[]
mySequence
= new
int
[] {1,2,3,4
};
for (
int
i
=0;
i
<
mySequence.length
;
i
++) {
System.out.println
(
mySequence
[
i
]);
}
Iterating over this sequence is coupled with its implementation.Slide7
The Sequence Interface
A little better:
List<Integer>
mySequence
= new
LinkedList
<>
{1,2,3,4
};
foreach
(
int
j :
mySequence
)
{
System.out.println
(
j
);
}
But still not perfect.Slide8
The Sequence Interface
OOP languages support collections
FP is better: sequence operations
Java 8 new feature is sequence operations… Scheme had it for years!Slide9
What is Sequence Interface?
ADT for lists
In other words: a barrier between clients running sequence applications and their implementations
Abstracts-away element by element manipulationSlide10
Map
Applies a procedure to all elements of a list. Returns a list as a result
;Signature:
map(
proc,sequence
)
;Purpose: Apply ’proc’ to all ’sequence’.
;Type: [[T
1
-> T
2
]*LIST(T
1
) -> LIST(T
2
)]
;Examples:
;(map abs (list -10 2.5 -11.6 17))
; ==> (10 2.5 11.6 17)
;(map (lambda (x) (* x
x
)) (list 1 2 3 4))
; ==> (1 4 9 16)
;Post-condition: For all
i
=1..length(sequence):
resulti
= proc(
sequencei
)Slide11
Map in Java?
A little better:
List<Integer>
mySequence
= new
LinkedList
<>
{1,2,3,4
};
mySequence.map
((lambda (
i
)
(
sysout
i
)))
Perfect!Slide12
Map Example:
scale-list
Scaling list of numbers by a factor
;Signature: scale-list(
items,factor
)
;Purpose: Scaling elements of a number list by a factor.
;Type: [LIST(Number)*Number -> LIST(Number)]
> (
scale
-
list
(
list
1 2 3 4 5) 10)
(10 20 30 40 50)Slide13
Implementation of
scale-list
No Map
(define scale-list
(lambda (items factor)
(if (null? items)
(list)
(cons (*
(car items)
factor)
(scale-list
(
cdr
items)
factor)))))
Map
(define scale-list
(lambda (items factor)
(
map
(lambda (x)
(* x factor))
items))Slide14
Map Example:
scale-tree
Mapping over hierarchical lists
>
(scale-tree
(list 1
(list 2 (list 3 4) 5)
(list 6 7))
10)
(10 (20 (30 40) 50) (60 70))Slide15
Implementation of
scale-tree
No Map
(define scale-tree
(lambda (tree factor)
(
cond
((null? tree)
(list))
((not (list? tree))
(* tree factor))
(else
(cons
(scale-tree
(car tree)
factor)
(scale-tree
(
cdr
tree)
factor))))))
Map
(define scale-tree
(lambda (tree factor)
(map (lambda (sub-tree)
(if (list? sub-tree)
(scale-tree
sub-tree
factor)
(*
sub-tree
factor)))
tree)))Slide16
Map in Java
List<Integer> list =
Arrays.asList
(1, 2, 3, 4, 5, 6, 7);
//Old way:
for(Integer n: list) {
System.out.println
(n);
}
//New way:
list.forEach
(
n ->
System.out.println
(n)
);
//Scheme
(map list (lambda(n) (display n))Slide17
Implementation of Map
;Signature: map(
proc,items
)
;Purpose: Apply ’proc’ to all ’items’.
;Type: [[T
1
-> T
2
]*LIST(T
1
) -> LIST(T
2
)]
(define map
(lambda (proc items)
(if (null? items)
(list)
(cons (proc (car items))
(map proc (
cdr
items))))))Slide18
A More General Map
So far, the procedure can get only a single parameter: an item in the list
Map in Scheme is more general: n-
ary
procedure and n lists (with same length)
Example:
> (map +
(list 1 2 3)
(list 40 50 60)
(list 700 800 900))
(741 852 963)Slide19
Haskell CurrySlide20
Function Currying: Reminder
Technique for turning a function with
n
parameters to
n
functions with a single parameter
Good for partial evaluationSlide21
Currying
;Type: [Number*Number -> Number]
(define add
(
λ (
x y)
(+ x y)))
;Type: [Number -> [Number -> Number]]
(define c-add
(
λ (
x)
(
λ (
y)
(add x y))))
(define add3 (c-add 3))
(add3 4)
7Slide22
Why Currying?
(define
add-fib
(lambda (x y)
(+ (
fib
x) y)))
(define c-
add
-
fib
(lambda (x)
(lambda (y)
(+ (
fib
x) y))))
(define c-
add
-
fib
(lambda (x)
(
let
((
fib
-x (
fib
x)))
(lambda (y)
(+
fib
-x y)))))Slide23
Curried Map Delayed List Naïve Version:
;Signature: c-map-proc(proc)
;Purpose: Create a delayed map for ’proc’.
;Type: [[T
1
-> T
2
] -> [LIST(T
1
) -> LIST(T
2
)]]
(define c-map-proc
(lambda (proc)
(lambda (
lst
)
(if (empty?
lst
)
lst
(cons
(proc (car
lst
))
((c-map-proc proc) (
cdr
lst
)))))))Slide24
Curried Map – delay the list
(define c-map-proc
(lambda (proc)
(
letrec
((
iter
(lambda (
lst
)
(if (empty?
lst
)
lst
(cons
(proc (car
lst
))
(
iter
(
cdr
lst
)))))))
iter
)))Slide25
Curried Map – delay the
proc
;; Signature: c-map-list(
lst
)
;; Purpose: Create a delayed map for ’
lst
’.
;; Type: [LIST(T
1
) -> [[T
1
-> T
2
] -> LIST(T
2
)]]
(define c-map-list
(lambda (
lst
)
(if (empty?
lst
)
(lambda (
proc
)
lst
)
; c-map-list returns a procedure
(let ((mapped-
cdr
(c-map-list (
cdr
lst
))))
;Inductive Currying
(lambda (proc)
(cons (proc (car
lst
))
(mapped-
cdr
proc)))))))Slide26
Filter Homogenous List
Signature:
filter(predicate, sequence)
Purpose: return a list of all sequence elements that satisfy the predicate
Type: [[T-> Boolean]*LIST(T) -> LIST(T)]
Example: (filter odd? (list 1 2 3 4 5)) ==> (1 3 5)
Post-condition: result = sequence - {
el|el∈sequence
and not(predicate(el))}``Slide27
Accumulate Procedure Application
Signature:
accumulate(
op,initial,sequence
)
Purpose: Accumulate by ’op’ all sequence elements, starting (ending)
with ’initial’
Type: [[T
1
*T
2
-> T
2
]*T
2
*LIST(T
1
) -> T
2
]
Examples: (accumulate + 0 (list 1 2 3 4 5)) ==> 15
(accumulate * 1 (list 1 2 3 4 5)) ==> 120Slide28
Interval Enumeration
Signature:
enumerate-interval(low, high)
Purpose: List all integers within an interval:
Type: [Number*Number -> LIST(Number)]
Example: (enumerate-interval 2 7) ==> (2 3 4 5 6 7)
Pre-condition: high > low
Post-condition: result = (low low+1 ... high)Slide29
Enumerate Tree
Signature:
enumerate-tree
(tree)
Purpose: List all leaves of a number tree
Type: [LIST union T -> LIST(Number)]
Example: (enumerate-tree (list 1 (list 2 (list 3 4)) 5)) ==> (1 2 3 4 5)
Post-condition: result = flatten(tree)Slide30
Sum-odd-squares
; Signature: sum-odd-squares(tree)
; Purpose: return the sum of all odd square leaves
; Type: [LIST -> Number]
(define sum-odd-squares
(lambda (tree)
(accumulate
+
0
(map square
(filter odd?
(enumerate-tree tree))))))Slide31
Even Fibonacci Numbers
Without sequence operations:
(define even-fibs
(lambda (n)
(
letrec
((next
(lambda(k)
(if (> k n)
(list)
(let ((f (fib k)))
(if (even? f)
(cons
f
(next (+ k 1)))
(next
(+ k 1))))))))
(next 0))))
With sequence operations:
(define even-fibs
(lambda (n)
(accumulate
cons
(list)
(filter
even?
(map fib
(enumerate-interval
0
n))))))Slide32
Filter implementation
;; Signature: filter(predicate, sequence)
;; Purpose: return a list of all sequence elements that satisfy the predicate
;; Type: [[T-> Boolean]*LIST(T) -> LIST(T)]
(define filter
(lambda (predicate sequence)
(
cond
((null? sequence) sequence)
((predicate (car sequence))
(cons (car sequence)
(filter predicate (
cdr
sequence))))
(else
(filter predicate (
cdr
sequence))))))Slide33
Accumulate Implementation
;; Signature: accumulate(
op,initial,sequence
)
;; Purpose: Accumulate by ’op’ all sequence elements, starting (ending)
;; with ’initial’
;; Type: [[T
1
*T
2
-> T
2
]*T
2
*LIST(T
1
) -> T
2
]
(define accumulate
(lambda (op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (
cdr
sequence))))))Slide34
Enumerate-interval Implementation
;; Signature
: enumerate-interval(low, high)
;; Purpose
: List all integers within an interval:
;; Type
: [Number*Number -> LIST(Number)]
(define enumerate-interval
(lambda (low high)
(if (> low high)
(list)
(cons
low
(enumerate-interval (+ low 1) high)))))Slide35
Enumerate-Tree Implementation
;; Signature
: enumerate-tree(tree)
;; Purpose
: List all leaves of a number tree
;; Type
: [LIST union T -> LIST(Number)]
(define enumerate-tree
(lambda (tree)
(
cond
((null? tree) (tree))
((not (list? tree)) (list tree))
(else
(append
(enumerate-tree (car tree))
(enumerate-tree (
cdr
tree)))))))