Practice session 7 ממשק Sequence Lazy Lists נושאי התרגול The Sequence Interface רוצים לבצע פעולה כלשהי על אוסף למשל להוסיף 1 לכל האיברים ID: 254082
Download Presentation The PPT/PDF document "Principles of Programming Languages" 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
Principles of Programming Languages
Practice session
7Slide2
ממשק
Sequence
Lazy Lists
נושאי
התרגולSlide3
The Sequence Interface
רוצים לבצע פעולה כלשהי על אוסף, למשל להוסיף 1 לכל האיברים.
ב-
Java
:
for (int
i = 0; i < listLen; i++) {
ourList[i] =
ourList[i
] + 1
;
}
ב-
Scheme
:
Signature
:
func
(
ls
)
Type
: [LIST(Number)->LIST(Number)]
(define
func
(lambda (
ls
)
(if (null?
ls
)
ls
(cons (+ 1 (car
ls
))
(
func
(
cdr
ls
))))))
ע"י שימוש בפונקציה
map
של הממשק
Sequence
:
> (define
func
(lambda (
ls
)
(
map
(lambda (x) (+ 1 x))
ls
)))Slide4
The Sequence Interface
פונקציות בממשק
Sequence
:
map
: מפעילה פונקציה על כל איברי הרשימה.
f
ilter
: מסננת איברים מתוך רשימה. הסינון נעשה ע"י פונקציה המחזירה ערך בוליאני.
> (filter
(
lambda(x)(
even? x))
(list 1 2 3 4 5 6))
'(2 4 6
)
a
ccumulate
: מבצעת פעולה בינארית, אסוציאטיבית לימין, על איברי הרשימה. ההפעלה הראשונה מתבצעת על האיבר האחרון ברשימה ועל איבר התחלתי נתון.
> (
accumulate + 0 (list 1 2 3 4 5))
15
> (
accumulate
expt
1 (list
4
3 2))
262144
ועוד...Slide5
The Sequence Interface
שאלה 1:
רוצים לממש
את הפרוצדורה
dists_k
שמקבלת רשימה
של זוגות מספרים המייצגים
קואורדינטות
(
x,y
)
, ומחזירה את המרחק מהראשית של כל הנקודות המקיימות
x=k
.
Signature
:
dists
_
k (
ls
k)
Type
: [LIST(Number*Number) ->LIST(Number)]
Examples:
(
dists_k
(list (cons 3 4) (cons 3 7) (cons 15 12) (cons 3 12)) 3) => '(5 7.615773105863909 12.36931687685298)
פונקציית
העזר הנ"ל נתונה לנו
:
> (define dist (lambda (x y) (
sqrt
(+ (
sqr
x) (
sqr
y)))))Slide6
The Sequence Interface
שאלה 1:
רוצים לממש
את הפרוצדורה
dists_k
שמקבלת רשימה
של זוגות מספרים המייצגים
קואורדינטות
(
x,y), ומחזירה את המרחק מהראשית של כל הנקודות המקיימות x=k .> (define dist (lambda (x y) (sqrt (+ (sqr x) (sqr y)))))מימוש רקורסיבי, ללא ממשק Sequence:> (define dists_k (lambda (ls k) (if (null? ls) ls (let ((xcord (caar ls)) (ycord (cdar ls)) (rest (dists_k (cdr ls) k))) (if (= xcord k) (cons (dist xcord ycord) rest) rest)))))Slide7
The Sequence Interface
שאלה 1:
רוצים לממש
את הפרוצדורה
dists_k
שמקבלת רשימה
של זוגות מספרים המייצגים
קואורדינטות
(
x,y), ומחזירה את המרחק מהראשית של כל הנקודות המקיימות x=k .> (define dist (lambda (x y) (sqrt (+ (sqr x) (sqr y)))))מימוש בעזרת ממשק Sequence:> (define dists_k (lambda (ls k) (map (lambda (x) (dist (car x) (cdr x))) (filter (lambda (x) (= (car x) k)) ls))))Slide8
Currying
שאלה 1:
רוצים לממש
את הפרוצדורה
dists_k
שמקבלת רשימה
של זוגות מספרים המייצגים
קואורדינטות
(
x,y), ומחזירה את המרחק מהראשית של כל הנקודות המקיימות x=k .>(define dist (lambda (x y) (sqrt (+ (sqr x) (sqr y)))))מימוש בעזרת ממשק Sequence:> (define dists_k (lambda (ls k) (map (lambda (x) (dist (car x) (cdr x))) (filter (lambda (x) (= (car x) k)) ls))))שאלה 2: מה אפשר לשפר במימוש הנ"ל?Slide9
Currying
שאלה 2:
>(define dist (lambda (x y) (
sqrt
(+ (
sqr
x) (
sqr
y)))))
> (define
c_dist
(lambda (x) (let ((xx (sqr x))) (lambda(y) (sqrt (+ (sqr y) xx))))))מימוש dists_k החדש:> (define dists_k (lambda(ls k) (let ((dist_k (c_dist k))) (map (lambda (x) (dist_k (cdr x))) (filter (lambda (x) (= (car x) k)) ls)))))Slide10
Currying
שאלה 3:
ניזכר
בפונקציית
accumulate
כפי שראיתם
בהרצאה
:
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))))))Slide11
Currying
שאלה 3:
רוצים לבצע
Currying
(define accumulate
(lambda (op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (
cdr
sequence))))))Currying נאיבי: (define c-accumulate-naive (lambda (op initial) (lambda (sequence) (if (null? sequence) initial (op (car sequence) ((c-accumulate-naive op initial) (cdr sequence)))))))Slide12
Currying
Currying
נאיבי:
(define c-accumulate-naive
(lambda (op initial)
(lambda (sequence)
(if
(null? sequence)
initial
(op (car sequence)
(
(c-accumulate-naive op initial) (cdr sequence)))))))> (define add-accum (c-accumulate-naive + 0))> (add-accum '(1 2 3))> (add-accum '(4 5 6))מה קורה כאן וכאן וכאן?Slide13
Currying
שאלה 3:
רוצים לבצע
Currying
(define accumulate
(lambda (op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (
cdr
sequence))))))Currying חכם יותר:> (define c-accumulate-op-initial (lambda (op initial) (letrec ((iter (lambda (sequence) (if (null? sequence) initial (op (car sequence) (iter (cdr sequence))))))) iter)))> (define add-accum (c-accumulate-op-initial + 0))> (add-accum '(1 2 3))> (add-accum '(4 5 6))
מה קורה כאן וכאן
וכאן
?Slide14
Currying
שאלה 3:
רוצים לבצע
Currying
(define accumulate
(lambda (op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (
cdr
sequence))))))Currying חכם יותר2:> (define c-accumulate-sequence (lambda (sequence) (if (null? sequence) (lambda (op initial) initial) (let ((rest (c-accumulate-sequence (cdr sequence)))) (lambda (op initial) (op (car sequence) (rest op initial)))))))> (define lst-accum (c-accumulate-sequence '(1 2 3)))> (lst-accum + 0)6> (lst-accum * 1)6מה קורה כאן וכאן וכאן?Slide15
The Sequence
Inteface
שאלה 4:
רוצים לממש
את הפרוצדורה
flatmap
המקבלת רשימה ופרוצדורה, מפעילה על איברי הרשימה את הפרוצדורה ולאחר מכן משטחת את הרשימה.
Signature
:
flatmap
(proc seq)Type: [ [T1->T2] * List(T1) -> List(T3)]Purpose: Applies a function on every element of the given list, resulting in a new nested listFlattens the nested list (not recursively).דוגמת הרצה:> (define ls (list (list 1 2 3) (list 4 6 7) (list 8 9)))> (flatmap cdr ls) => '(2 3 6 7 9)> (flatmap (lambda (lst)(filter odd? lst)) ls) => '(1 3 7 9)Slide16
The Sequence
Inteface
שאלה 4:
Signature
:
flatmap
(proc
seq
)
Type:
[ [T1->T2] * List(T1) ->
List(T2)]Purpose: Applies a function on every element of the given list, resulting in a new nested listFlattens the nested list (not recursively).(define flatmap (lambda (proc seq) (accumulate append (list) (map proc seq))))Slide17
Lazy Lists
תזכורת: רשימות עצלות הן מבני נתונים סדרתיים המאפשרים דחייה של חישוב ושמירה של איברים מתוכם.
יתרונות
:
אין צורך לאחסן בזיכרון את כל איברי הרשימה.
ניתן לייצג סדרות
אין-סופיות.
דחיית חישוב איברים ברשימה לזמן בו
נזדקק להם
– ייתכן שלא נזדקק לכל איברי
הרשימה.
הטיפוס של LazyList: LazyList = ‘() U T*[Empty->LazyList]Slide18
Lazy Lists
ממשק:
Signature
: cons(head, tail)
Type:
[T * [Empty->
LazyList
] ->
LazyList
]
Purpose
: Value constructor for lazy lists Signature: head(lzl)Type: [LazyList -> T]Purpose: Selector for the first item of lzl (a lazy list)Pre-condition: lzl is not empty Signature: tail(lzl)Type: [LazyList -> LazyList]Purpose: Selector for the tail (all but the first item) of lzl (a lazy list)Pre-condition: lzl is not empty Signature: nth(lzl, n)Type: [LazyList * Number -> T]Purpose: Gets the n-th item of lzl (a lazy list)Pre-condition: lzl length is at least n, n is a natural numberPost-condition: result=lzl[n-1] Signature: take(lzl, n) Type: [LazyList * Number -> List] Purpose: Creates a List out of the first n items of lzl (a lazy list) Pre-condition: lzl length is at least n, n is a natural number Post-condition: result[i]=lzl[i] for any i in range 0::n-1 Slide19
Lazy Lists
שאלה 5:
רוצים לממש פונקציה שתיצור
lazy list
כנ"ל:
Signature
: integers-from (low)
Purpose
: Creates a lazy list containing all integers bigger than
n-1 by
their order
Pre-condition: n is an integer > (define integers-from (lambda(n) (cons n (lambda () (integers-from (+ 1 n)))))) > (head (integers-from 5))5> (head (tail (integers-from 5))))6Slide20
Lazy Lists
שאלה 6:
רוצים לממש רשימה שתספור לפי חוקי
7BOOM
.
> (define
gen_item
(
lambda (n
)
(cons (if (or (divided_by_7? n) (has_digit_7? n)) 'boom n) (lambda () (gen_item (+ n 1))))))> (gen_item 1)'(1 . #<procedure>) > (take (gen_item 1) 7)'(1 2 3 4 5 6 boom)מה הטיפוס של (gen-item 1)? והאם הביטוי הוא well-typed?Slide21
Lazy Lists
שאלה 7:
רוצים לממש רשימה עצלה של המספרים הראשוניים ע"י שימוש בממשק
Sequence
.
>(
define primes
(
cons 2 (
lambda()(
lz-lst-filter prime? (integers-from 3))))) >(define prime? (lambda (n) (letrec ((iter (lambda (lz) (cond ((> (sqr (head lz)) n) #t) ((divisible? n (head lz)) #f) (else (iter (tail lz))))) )) (iter (integers-from 2))) )) > (take primes 6)’(2 3 5 7 11 13)Slide22
Lazy Lists
שאלה 7:
רוצים לממש רשימה עצלה של המספרים הראשוניים ע"י שימוש בממשק
Sequence
– אלגוריתם הנפה.
> (define sieve
(lambda (
lz
)
(cons (head
lz
) (lambda () (sieve (lz-lst-filter (lambda(x) (not (divisible? x (head lz)))) (tail lz))))) )) > (define primes1 (sieve (integers-from 2)))