Standard ML Sequences ML Sequences.1 Sequences, Lazy Lists  Characteristics of lazy lists  Elements are not evaluated until their values are required  May be.

Download Report

Transcript Standard ML Sequences ML Sequences.1 Sequences, Lazy Lists  Characteristics of lazy lists  Elements are not evaluated until their values are required  May be.

Slide 1

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 2

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 3

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 4

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 5

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 6

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 7

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 8

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 9

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 10

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬


Slide 11

Standard ML

Sequences

ML Sequences.1

Sequences, Lazy Lists
 Characteristics of lazy lists
 Elements are not evaluated until their values are required
 May be infinite

 Expressing lazy lists in ML
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x;
> val head = fn : 'a seq -> 'a
fun tail(Cons(_,xf)) = xf();
> val tail = fn : 'a seq -> 'a seq

 ML evaluates the E expression in Cons(x,E), so to
obtain lazy evaluation we must write Cons(x,fn()=>E).
ML Sequences.2

Examples Of Sequences
 An increasing sequence of integers
fun from k = Cons(k,fn()=>from(k+1));
> val from = fn : int -> int seq
from 1;
> val it = Cons (1, fn) : int seq
tail it;
> val it = Cons (2, fn) : int seq

 A sequence of squared integers
fun squares Nil : int seq = Nil
| squares (Cons(x,xf)) =
Cons(x*x, fn()=> squares (xf()));
> val squares = fn : int seq -> int seq
squares (from 1);
> val it = Cons (1, fn) : int seq
head(tail(tail(tail(tail it))))
> val it = 25 : int
ML Sequences.3

Elementary Sequence Processing
 Adding two sequences
 fun addq (Cons(x,xf), Cons(y,yf))=
Cons(x+y, fn()=>addq(xf(),yf()))
| addq _ : int seq = Nil;
> val addq = fn: int seq * int seq -> int seq

 Appending two sequences
 fun appendq (Nil,
yq) = yq
| appendq (Cons(x,xf), yq) =
Cons(x,fn()=>appendq(xf(),yq));
> val appendq = fn : 'a seq * 'a seq -> 'a seq
 appendq (xq, yq) :
No elements of yq appear in the output unless xq is finite !
ML Sequences.4

Functionals for Sequences


Interleaving two sequences
 fun interleaving (Nil, yq)
= yq
| interleaving (Cons(x,xf),yq) =
Cons(x, fn()=>interleaving(yq,xf()));
> val interleaving = fn: 'a seq * 'a seq -> 'a seq



mapq and filterq
 fun mapq f Nil
= Nil
| mapq f (Cons(x,xf)) =
Cons( f(x), fn()=>mapq f (xf()) );
>

val mapq = fn : ('a ->'b) -> 'a seq -> 'b seq

 fun filterq pred Nil
= Nil
| filterq pred (Cons(x,xf)) =
if pred x then Cons(x,fn()=>filterq pred (xf()))
else filterq pred (xf());
> val filterq = fn : ('a ->bool) -> 'a seq -> 'a seq
ML Sequences.5

Sieve of Eratosthenes

[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes]

ML Sequences.6

Example: Prime numbers


fun notDivide p = filterq (fn n => n mod p <> 0);
> val notDivide = fn : int -> int seq -> int seq
notDivide p builds a filter that removes all numbers that are divisible
by p.



fun sieve (Cons(p,nf)) =
Cons(p, fn () => sieve(notDivide p (nf())));
> val sieve = fn : int seq -> int seq
Sieve receives a sequence and returns a sequence in which every
head places a notDivide filter on the tail; therefore the tail never has
numbers that are divisible by any number that has ever been in the head.



val primes = sieve (from 2);
> val primes = Cons (2, fn) : int seq
ML Sequences.7

)'‫ מועד ב‬2013 ‫שאלה ממבחן (אביב‬
:‫עבור שאלה זו ניזכר בהגדרת רצף שראינו בכיתה‬
datatype 'a

seq =

Nil

|

Cons of 'a * (unit -> 'a seq);
:‫ שראינו גם כן בכיתה‬,‫ובפונקציות הבאות‬

fun tail (Cons(_,xf)) = xf();
fun from(x) = Cons(x,fn()=>from(x+1));
fun mapq f Nil = Nil
| mapq f (Cons(x,xf)) = Cons(f(x), fn()=>mapq f (xf()));
fun mapq_3 f Nil = Nil
| mapq_3 f (Cons(x,xf)) = if (x mod 3 = 0 ) then
Cons(f(x), fn()=>mapq_3 f (xf()))
else Cons(x, fn()=>mapq_3 f (xf()));
: ‫ שלא ראינו בתרגול‬,‫כן כמו נגדיר את שתי הפונקציות הבאות‬

ML Sequences.8

)‫שאלה ממבחן (המשך‬

. ‫ לאחר הכנסת כל אחת מהפקודות הבאות‬ML ‫רשמו מה יהיה הפלט של‬
!‫ יש לרשום את הפלט לאחר הכנסת הפקודה האחרונה בקבוצת הפקודות‬,‫עבור סעיפים בהן ישנה יותר מפקודה אחת‬
)‫ נק‬2( .‫א‬
mysterySeq_1 op+ (from 0);
val it = Cons (0,fn) : int seq
)‫ נק‬3( .‫ב‬
mysterySeq_1 op+ (from 0);
tail (tail (tail it));
val it = Cons (7,fn) : int seq
)‫ נק‬3( .‫ג‬
mysterySeq_2 op+ (from 0);
tail (tail (tail it));
val it = Cons (4,fn) : int seq
)‫ נק‬3( .‫ד‬
mysterySeq_2 op+ (from 0);
tail (tail (tail (tail it)));
val it = Cons (4,fn) : int seq
ML Sequences.9

‫שאלה ממבחן (אביב ‪)2008‬‬
‫נציג את ההגדרה של ‪ sequences‬שנלמדה בכיתה ‪:‬‬
‫;)‪datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq‬‬
‫כמו כן נציג את הכרזת ‪ from‬כפי שנלמדה בכיתה ‪:‬‬

‫;))‪fun from k = Cons(k,fn()=>from(k+1‬‬

‫בשאלות הבאות ניתן להיעזר בכל פונקציה שנלמדה בתרגול‪ .‬כמו כן‪ ,‬בכל סעיף ניתן להשתמש בסעיף קודם‪ ,‬גם‬
‫במידה ולא מימשת את הפונקציה בו‪.‬‬
‫א‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬אשר מקבלת ‪ sequence‬ומחזירה ‪ true‬אם הוא שווה ל ‪.Nil‬‬
‫;‪fun isNil(Nil) = true | isNil(_) = false‬‬
‫ב‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס הזוגי‬
‫ברצף המקורי (האינדקס של האיבר הראשון הוא ‪.) 1‬‬
‫‪fun evens(Nil) = Nil‬‬
‫‪|evens(sq) = if isNil(tail(sq)) then Nil‬‬
‫‪else‬‬
‫;))))‪Cons(head(tail(sq)), fn() => evens(tail(tail(sq‬‬
‫ג‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחזיר רצף אשר מכיל רק את האיברים בעלי האינדקס האי‬
‫זוגי ברצף המקורי‪.‬‬
‫| ‪fun odds(Nil) = Nil‬‬
‫;)))‪odds(sq) = Cons(head(sq), fn() => evens(tail(sq‬‬
‫‪ML Sequences.10‬‬

‫שאלה ממבחן (אביב ‪)2008‬‬
‫ד‪ .‬מה תהיה תגובת ‪ ML‬להכרזה הבאה‪:‬‬
‫;))))‪val x = head (tail(evens(tail(from(1‬‬
‫‪val x = 5 : int‬‬
‫ה‪ .‬השלימו את הפונקציה הבאה ב ‪ ML‬כך שתקבל רצף ותחליף בין המיקומים של כל איבר באינדקס אי זוגי ברצף‬
‫והאיבר שבאינדקס הזוגי העוקב לו (אם כזה קיים)‪ .‬לדוגמא עבור רצף שאיבריו הם ‪ 1,2,3,4,5,6,7‬יוחזר הרצף‬
‫שאיבריו הם ‪ .2,1,4,3,6,5,7‬ניתן להניח כי הרצף שמתקבל אינו ‪.Nil‬‬
‫;))‪fun switch(sq) = interleaving(evens(sq),odds(sq‬‬

‫‪ML Sequences.11‬‬