Can We Represent Infinite Lists? Lazy Evaluation Amtoft Motivation Lazy Lists Conversions to/from Certain collections are infinite, like the set of all natural Standard Lists Higher-Order Functions numbers. We may try Merging Lazy Lists Larger Examples all numbers n = fun Primes Giving Change n : : ( all numbers (n+1)) which has type i n t − > i n t l i s t but all numbers 1 does not terminate and hence produces no result.
Lazy Evaluation Lazy Evaluation Amtoft Motivation Lazy Lists Conversions to/from Standard Lists Higher-Order Functions Key idea: Merging Lazy Lists Larger Examples ◮ evaluate lists one element at a time Primes Giving Change ◮ generate an element only when needed ◮ the list tail is thus not fully evaluated yet We may thus attempt all numbers n = fun n : : ( fn () = > all numbers (n+1)) but this is not quite type correct.
Lazy Lists Lazy Evaluation Amtoft datatype ’ a l s e q = Motivation N i l Lazy Lists Conversions to/from Standard Lists | Cons of ’ a ∗ ( u n i t − > ’ a l s e q ) Higher-Order Functions Merging Lazy Lists We define hd , tl with types Larger Examples Primes hd : ’ a l s e q − > ’ a t l : ’ a l s e q − > ’ a l s e q Giving Change exception Empty fun hd N i l = r a i s e Empty | hd ( Cons ( x , )) = x t l N i l = r a i s e Empty fun | t l ( Cons ( , s f )) = s f () We can now define a sequence containing all numbers: fun numbers n = Cons (n , () = > numbers (n+1)) fn . . . fn i n t − > i n t l s e q
Converting a List to a Lazy List Lazy Evaluation Amtoft Motivation Lazy Lists Conversions to/from Standard Lists Higher-Order Functions Merging Lazy Lists We want functionality Larger Examples Primes ’ a l i s t − > ’ a l s e q Giving Change which can be accomplished by l i s t 2 l s e q [ ] = N i l fun | l i s t 2 l s e q ( x : : xs ) = Cons ( x , fn () = > l i s t 2 l s e q xs )
Extracting a List from a Lazy List Lazy Evaluation Amtoft ◮ we cannot extract all elements Motivation Lazy Lists ◮ but would like to extract first n elements Conversions to/from Standard Lists Higher-Order Functions We thus aim at functionality Merging Lazy Lists Larger Examples i n t − > ’ a l s e q − > ’ a l i s t Primes Giving Change which can be accomplished by fun take 0 l s = [ ] | take n N i l = r a i s e Empty | take n ( Cons ( x , s f )) = x : : ( take (n − 1) ( s f ( ) ) ) Running take 7 ( numbers 2) thus gives us [2 ,3 ,4 ,5 ,6 ,7 ,8]
Map for Lazy Sequences Lazy Evaluation Amtoft Recall that map has type Motivation ( ’ a − > ’b) − > ’ a l i s t − > ’b l i s t Lazy Lists Conversions to/from Standard Lists We want to define lmap with type Higher-Order Functions Merging Lazy Lists ( ’ a − > ’b) − > ’ a l s e q − > ’b l s e q Larger Examples Primes which can be accomplished by Giving Change fun lmap f N i l = N i l | lmap f ( Cons ( x , s f )) = Cons ( f ( x ) , fn () = > lmap f ( s f ( ) ) ) We can now run take 7 ( lmap ( fn ( x ) = > x ∗ 2) ( numbers 1 ) ) ; [2 ,4 ,6 ,8 ,10 ,12 ,14] : i n t l i s t
Filter for Lazy Sequences Lazy Evaluation Amtoft Similarly, we want to define lfilter with type Motivation ( ’ a − > bool ) − > ’ a l s e q − > ’ a l s e q Lazy Lists Conversions to/from Standard Lists which can be accomplished by Higher-Order Functions Merging Lazy Lists Larger Examples l f i l t e r p N i l = N i l fun Primes | l f i l t e r p ( Cons ( x , s f )) = Giving Change p( x ) i f then Cons ( x , fn () = > l f i l t e r p ( s f ( ) ) ) l f i l t e r p ( s f ( ) ) else We can now run take 7 ( l f i l t e r ( fn x = > x mod 3 = 0) ( numbers 1 ) ) ; [3 ,6 ,9 ,12 ,15 ,18 ,21]
Non-Fair Merge Lazy Evaluation Amtoft Recall the append function Motivation fun append ( n i l , l s ) = l s Lazy Lists Conversions to/from | append (n : : ns , l s ) = n : : append ( ns , l s ) ; Standard Lists Higher-Order Functions Merging Lazy Lists We may want to define Larger Examples Primes lappend N i l l s = l s fun Giving Change | lappend ( Cons ( x , s f )) l s = Cons ( x , () = fn > lappend ( s f ( ) ) l s ) ’ a l s e q − > ’ a l s e q − > ’ a l s e q but when running take 7 ( lappend ( numbers 100) ( numbers 1 ) ) ; the second list is ignored: [100 ,101 ,102 ,103 ,104 ,105 ,106]
Fair Merge Lazy Evaluation Amtoft Instead, we repeatedly swap the two lists: Motivation Lazy Lists fun i n t e r l e a v e N i l l s = l s Conversions to/from Standard Lists | i n t e r l e a v e ( Cons ( x , s f )) l s = Higher-Order Functions Merging Lazy Lists Cons ( x , fn () = > Larger Examples i n t e r l e a v e l s ( s f ( ) ) ) Primes Giving Change which still has type ’ a l s e q − > ’ a l s e q − > ’ a l s e q and when running take 7 ( i n t e r l e a v e ( numbers 100) ( numbers 1 ) ) ; we do get the desired alternation: [100 ,1 ,101 ,2 ,102 ,3 ,103]
Sieve of Eratosthenes Lazy Evaluation Amtoft Motivation val primes = Lazy Lists s i e v e ( Cons (p , s f )) = l e t Conversions to/from l e t fun Standard Lists Higher-Order Functions fun p n o t d i v x = ( x mod p > 0) Merging Lazy Lists in Cons (p , fn () = Larger Examples > Primes s i e v e ( l f i l t e r Giving Change p n o t d i v ( s f ( ) ) ) ) end in s i e v e ( numbers 2) end − primes ; val i t = Cons (2 , fn ) : i n t l s e q − take 10 primes ; val i t = [2 ,3 ,5 ,7 ,11 ,13 ,17 ,19 ,23 ,29] : i n t l i s t
Giving Change Lazily Lazy Evaluation Amtoft Motivation fun mk change c o i n v a l s amount = l e t Lazy Lists ( ∗ s o l i s s o l u t i o n c u r r e n t l y b u i l t ; Conversions to/from Standard Lists s f () b u i l d s r e s t of s o l u t i o n s ∗ ) Higher-Order Functions Merging Lazy Lists fun chg 0 s o l s f = Cons ( sol , s f ) Larger Examples | chg [ ] n s f = s f () Primes Giving Change | chg ( cv1 : : cvs ) n s o l s f = n < 0 then s f () i f else chg ( cv1 : : cvs ) (n − cv1 ) ( cv1 : : s o l ) ( fn () = > chg cvs n s o l s f ) in chg c o i n v a l s amount [ ] ( fn () = > N i l ) end i n t l i s t − > i n t − > i n t l i s t l s e q
Example Changes, I Lazy Evaluation Amtoft Motivation Lazy Lists Conversions to/from Standard Lists val cg1 = mk change [ 5 , 2 ] 16 Higher-Order Functions Merging Lazy Lists Larger Examples We can extract two solutions: Primes Giving Change take 2 cg1 ; [ [ 2 , 2 , 2 , 5 , 5 ] , [ 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ] ] but is there a third? take 3 cg1 ; uncaught exception Empty
Example Changes, II Lazy Evaluation Amtoft Motivation Lazy Lists Conversions to/from val cg2 = mk change [25 ,10 ,5 ,1] 46 Standard Lists Higher-Order Functions Merging Lazy Lists displays the first solution: Larger Examples Primes Cons ([1 ,10 ,10 ,25] , fn ) : i n t l i s t l s e q Giving Change We can see that there are 39 solutions: − take 39 cg2 ; i t = [ [ 1 , 1 0 , 1 0 , 2 5 ] , [ 1 , 5 , 5 , 1 0 , 2 5 ] , . . ] val but not 40 solutions: − take 40 cg2 ; uncaught exception Empty
Recommend
More recommend