Download PPL

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
PPL
Sequence Interface
(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)))))
The Sequence Interface
• OOP languages support collections
• FP is better: sequence operations
• Java 8 new feature is sequence operations…
Scheme had it for years!
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
manipulation
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: [[T1 -> T2]*LIST(T1) -> LIST(T2)]
;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)
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)
Implementation of scale-list
No Map
Map
(define scale-list
(lambda (items factor)
(if (null? items)
(list)
(cons (*
(car items)
factor)
(scale-list
(cdr items)
factor)))))
(define scale-list
(lambda (items factor)
(map
(lambda (x)
(* x factor))
items))
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))
Implementation of scale-tree
No Map
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))))))
(define scale-tree
(lambda (tree factor)
(map (lambda (sub-tree)
(if (list? sub-tree)
(scale-tree
sub-tree
factor)
(*
sub-tree
factor)))
tree)))
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))
Implementation of Map
;Signature: map(proc,items)
;Purpose: Apply ’proc’ to all ’items’.
;Type: [[T1 -> T2]*LIST(T1) -> LIST(T2)]
(define map
(lambda (proc items)
(if (null? items)
(list)
(cons (proc (car items))
(map proc (cdr items))))))
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)
Haskell Curry
Function Currying: Reminder
• Technique for turning a function with n
parameters to n functions with a single
parameter
• Good for partial evaluation
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)
7
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)))))
Curried Map Delayed List Naïve
Version:
;Signature: c-map-proc(proc)
;Purpose: Create a delayed map for ’proc’.
;Type: [[T1 -> T2] -> [LIST(T1) -> LIST(T2)]]
(define c-map-proc
(lambda (proc)
(lambda (lst)
(if (empty? lst)
lst
(cons
(proc (car lst))
((c-map-proc proc) (cdr lst)))))))
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)))
Curried Map – delay the proc
;Signature: c-map-list(lst)
;Purpose: Create a delayed map for ’lst’.
;Type: [LIST(T1) -> [[T1 -> T2] -> LIST(T2)]]
(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)))))))
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))}``
Accumulate Procedure Application
Signature: accumulate(op,initial,sequence)
Purpose: Accumulate by ’op’ all sequence
elements, starting (ending)
with ’initial’
Type: [[T1*T2 -> T2]*T2*LIST(T1) -> T2]
Examples: (accumulate + 0 (list 1 2 3 4 5)) ==> 15
(accumulate * 1 (list 1 2 3 4 5)) ==> 120
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)
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)
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))))))
Even Fibonacci Numbers
Without sequence operations:
With 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))))
(define even-fibs
(lambda (n)
(accumulate
cons
(list)
(filter
even?
(map fib
(enumerate-interval
0
n))))))
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))))))
Accumulate Implementation
;;Signature: accumulate(op,initial,sequence)
;;Purpose: Accumulate by ’op’ all sequence elements,
starting (ending)
;;with ’initial’
;;Type: [[T1*T2 -> T2]*T2*LIST(T1) -> T2]
(define accumulate
(lambda (op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence))))))
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)))))
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)))))))
Related documents