Introducción Funciones paraciales y Excepciones Metodologı́as de Programación II Dominios y Excepciones Dr. Alejandro Guerra-Hernández Departamento de Inteligencia Artificial Facultad de Fı́sica e Inteligencia Artificial [email protected] http://www.uv.mx/aguerra Maestrı́a en Inteligencia Artificial 2012 Definiendo Excepciones Introducción Funciones paraciales y Excepciones Definiendo Excepciones Tipos, Dominios y Excepciones I El tipo inferido de una función corresponde a un subconjunto del dominio de su definición. I Si el dominio de una función son los enteros, esto no significa que pueda trabajar con todos los enteros. I El mecanismo para trabajar con estos detalles se conoce como manejo de excepciones. I Provocar (raise) una excepción provoca una interrupción en el programa, que puede ser interceptada y procesada por éste mismo. Introducción Funciones paraciales y Excepciones Definiendo Excepciones Funciones parciales I El dominio de una definición es el conjunto de valores con los que la función lleva a cabo su cómputo. I Hay muchas funciones matemáticas que son parciales, ej. División, Logaritmo natural. I Lo mismo suele ocurrir con estructuras de datos complejas, ej. car de una lista vacı́a, factorial de un negativo. Introducción Funciones paraciales y Excepciones Definiendo Excepciones Excepciones I # 1/0 ;; Exception: Division_by_zero. 1 2 I 1 2 3 4 5 6 7 8 La división por cero produce una excepción. O las funciones parciales. # let car l = match l with h::t -> h ;; Characters 12-34: let car l = match l with h::t -> h ;; ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: [] val car : ’a list -> ’a = <fun> Introducción Funciones paraciales y Excepciones Ejemplo llamada I 1 2 Si mantenemos la definición de car /1: # car [] ;; Exception: Match_failure ("", 1, 12). Definiendo Excepciones Introducción Funciones paraciales y Excepciones Excepciones con failure I 1 2 3 4 5 6 Toman como argumento un string: # let car = function | [] -> failwith "Lista Vacia" | h::t -> h ;; val car : ’a list -> ’a = <fun> # car [] ;; Exception: Failure "Lista Vacia". Definiendo Excepciones Introducción Funciones paraciales y Excepciones Definiendo Excepciones Sintaxis I El tipo predefinido para las excepciones es exn. I Es un tipo suma extendible: el conjunto de valores del tipo puede extenderse declarando nuevos constructores. I Formas: exception Name;; y exception Name of t ;; Introducción Funciones paraciales y Excepciones Definiendo Excepciones Ejemplos de declaraciones I # exception MY_EXC ;; exception MY_EXC # exception Profundidad of int ;; exception Profundidad of int # Profundidad 5 ;; - : exn = Profundidad 5 1 2 3 4 5 6 I 1 2 3 4 5 Se declaran por constructores (mayúscula inicial): También son monomórficos: # exception Valor of ’a ;; Characters 19-21: exception Valor of ’a ;; ˆˆ Error: Unbound type parameter ’a Introducción Funciones paraciales y Excepciones Definiendo Excepciones Provocando una Excepción I 1 2 3 4 5 6 Toma como argumento una excepción y regresa tipos completamente polimórficos: # raise ;; - : exn -> ’a = <fun> # raise MY_EXC ;; Exception: MY_EXC. # raise (Profundidad 3) ;; Exception: Profundidad 3. Introducción Funciones paraciales y Excepciones Definiendo Excepciones Manejando Excepciones 1 2 3 4 5 6 7 8 I Provocar excepciones introduce un nuevo control de flujo. I Salimos del terreno puramente funcional. I No confundir el cómputo de una excepción y la producción de una excepción: # let computar x = Failure x ;; val computar : string -> exn = <fun> # computar "test" ;; - : exn = Failure "test" # let producir x = raise (computar x) ;; val producir : string -> ’a = <fun> # producir "test" ;; Exception: Failure "test". Introducción Funciones paraciales y Excepciones Uso: try ... with 1 2 3 4 5 6 7 8 9 10 11 12 13 # exception Zero_encontrado ;; exception Zero_encontrado # let rec mult_rec lst = match lst with | [] -> 1 | 0::_ -> raise Zero_encontrado | n::ns -> n*(mult_rec ns) ;; val mult_rec : int list -> int = <fun> # let mult_lista lst = try mult_rec lst with Zero_encontrado -> 0 ;; val mult_lista : int list -> int = <fun> # mult_lista [1;2;3;0;4] ;; - : int = 0 # mult_lista [1;2;3] ;; - : int = 6 Definiendo Excepciones