Exceptions Exceptions Amtoft from Hatcliff Raising Exceptions Handling Exceptions Application ML provides an elegant exception handling mechanism 1. built-in exceptions 2. partial functions 3. user-defined exceptions 4. exception handling 5. further applications
Built-in Exceptions Exceptions Amtoft from Hatcliff Raising Exceptions Handling Exceptions Application − 5 div 0; uncaught exception Div [ d i v i d e by zero ] r a i s e d at : . . . − chr (5 00); uncaught exception Chr r a i s e d at : . . . − hd ( n i l : i n t l i s t ) ; uncaught exception Empty r a i s e d at : . . .
Exceptions for Non-Total Functions Exceptions Amtoft from Hatcliff Some functions are naturally undefined for some input. Raising Exceptions Dealing with that can be awkward: Handling Exceptions fun l o o k u p t a b l e x n i l = NONE Application | l o o k u p t a b l e x (( x ’ , v ’ ) : : t ) = i f x = x ’ then SOME v ’ else l o o k u p t a b l e x t ; ( ∗ ’ ’ a − > ( ’ ’ a ∗ ’b) l i s t − > ’b option ∗ ) Instead, one may explicitly raise an exception: exception Empty table ; l o o k u p t a b l e x n i l = r a i s e Empty table fun | l o o k u p t a b l e x (( x ’ , v ’ ) : : t ) = i f x = x ’ then v ’ l o o k u p t a b l e x t ; else ( ∗ ’ ’ a − > ( ’ ’ a ∗ ’b) l i s t − > ’b ∗ )
Exceptions with Parameters Exceptions Amtoft from Hatcliff Empty table s t r i n g ; exception of Raising Exceptions l o o k u p t a b l e x n i l fun Handling Exceptions = r a i s e Empty table ( x ) Application | l o o k u p t a b l e x (( x ’ , v ’ ) : : t ) = i f x = x ’ then v ’ l o o k u p t a b l e x t ; else ( ∗ s t r i n g − > ( s t r i n g ∗ ’ a ) l i s t − > ’ a ∗ ) Note: polymorphism of function has been lost − l o o k u p t a b l e ”mary” [ ( ” joe ” ,12) ,( ”ed” , 7 ) ] ; uncaught exception Empty table − Empty table ; i t = fn : s t r i n g − > exn val − r a i s e Empty table ; Error : argument of i s not an exception r a i s e
Exception Handling Exceptions Amtoft from Hatcliff Wrap a handler around an exception returning expression: Raising Exceptions Handling Exceptions fun lookup table ’ x v Application = l o o k u p t a b l e x v handle Empty table ( s ) = > ( p r i n t ( ” Entry not found : ” ) ; p r i n t ( x ) ; p r i n t ( ” \ n” ) ; 0 ) ; ( ∗ s t r i n g − > ( s t r i n g ∗ i n t ) l i s t − > i n t ∗ ) − l o o k u p t a b l e ”ed” [ ( ” joe ” ,12) ,( ”ed” , 7 ) ] ; i t = 7 : i n t val − l o o k u p t a b l e ”mary” [ ( ” joe ” ,12) ,( ”ed” , 7 ) ] ; Entry not found : mary val i t = 0 : i n t
Giving Change Exceptions Amtoft from Hatcliff Problem: given a set of coins (infinite supply of each Raising Exceptions denomination), produce Handling Exceptions ◮ exact change for a given amount Application ◮ involving minimal number of coins. This may not always be possible return 7c using 5c coins and 3c coins but is always possible if we have 1c coins. ◮ We would like not to test all combinations Greedy Strategy: return as many as possible from highest denomination, then as many as possible from second-highest denomination, etc. ◮ this is not always optimal: return 8c using 5c,4c,1c ◮ but for US coin set { 25,10,5,1 } it is optimal (though not trivial to prove)
Greedy Implementation Exceptions Amtoft from Hatcliff fun change ( coins , 0 ) = [ ] Raising Exceptions | change ( c : : coins , amount ) = Handling Exceptions amount < c i f Application then change ( coins , amount ) ( ∗ take l a r g e s t coin p o s s i b l e ∗ ) else c : : change ( c : : coins , amount − c ) change ( [ 2 5 , 1 0 , 5 , 1 ] , 4 8 ) ; val i t = [25 ,10 ,10 ,1 ,1 ,1] : i n t l i s t change ( [ 5 , 2 ] , 1 6 ) ; uncaught exception Match [ nonexhaustive match f a i l u r e ] change ( [ 5 , 4 , 1 ] , 8 ) ; val i t = [ 5 , 1 , 1 , 1 ] : i n t l i s t
Exhaustive Search Exceptions Amtoft from Hatcliff ( ∗ expects : c u r r e n t s o l u t i o n , coins , amount Raising Exceptions r e t u r n s : l i s t of s o l u t i o n s ∗ ) Handling Exceptions F i n d A l l ( sol , , 0 ) = [ s o l ] fun | F i n d A l l ( , [ ] , ) = [ ] Application | F i n d A l l ( sol , c : : coins , amount ) = i f amount < 0 then [ ] else F i n d A l l ( c : : sol , c : : coins , amount − c ) @ F i n d A l l ( sol , coins , amount ) fun change exh ( coins , amount ) = F i n d A l l ( [ ] , coins , amount ) change exh ( [ 5 , 2 ] , 1 6 ) ; val i t = [ [ 2 , 2 , 2 , 5 , 5 ] , [ 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ] ] : i n t l i s t l i s t change exh ( [ 5 , 4 , 1 ] , 8 ) ; val i t = [ [ 1 , 1 , 1 , 5 ] , [ 4 , 4 ] , [ 1 , 1 , 1 , 1 , 4 ] , [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ] ] : i n t l i s t l i s t change exh ( [ 2 5 , 1 0 , 5 , 1 ] , 4 8 ) ;
Exceptions for Backtracking Exceptions Amtoft from Hatcliff F a i l u r e exception Raising Exceptions fun change1 ( coins , 0 ) = [ ] Handling Exceptions | change1 ( [ ] , amount ) = r a i s e F a i l u r e Application | change1 ( c : : coins , amount ) = i f amount < c then change1 ( coins , amount ) else ( c : : change1 ( c : : coins , amount − c ) handle F a i l u r e = > change1 ( coins , amount ) change1 ( [ 5 , 2 ] , 1 6 ) ; val i t = [ 5 , 5 , 2 , 2 , 2 ] : i n t l i s t change1 ( [ 2 5 , 1 0 , 5 , 1 ] , 4 8 ) ; i t = [25 ,10 ,10 ,1 ,1 ,1] : i n t l i s t val change1 ( [ 5 , 4 , 1 ] , 8 ) ; i t = [ 5 , 1 , 1 , 1 ] : i n t l i s t val
Recommend
More recommend