Tema 2: Introducción a Haskell

Documentos relacionados
Introducción a Haskell. El lenguaje Haskell

Tema 3. Patrones y Definiciones de Funciones

Tema 3. Patrones y Definiciones de Funciones

Tema 2. Tipos predefinidos

Tema II: Introducción al Lenguaje Funcional

Lógica y Programación

Introducción a Haskell. Cecilia Manzino

Tema 1: Programación Funcional

Funciones Segunda parte

Tema 5: Introducción a la programación funcional.

Práctica 1. Programación Funcional Introducción a Helium

GUÍA BÁSICA DE SCHEME v.4

Tema 7. El sistema de clases

Tema 6. Definiciones de tipos

Programación Funcional Haskell Clase 22

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

El sistema de clases de Haskell. Introducción

Informática Haskell Matemáticas Curso Pepe Gallardo Universidad de Málaga. Temario

Tema 3: Tipos y clases

Tema 3: Tipos y clases

Apunte Laboratorio ALPI - El lenguaje de programación Pascal

Tema 3: Tipos y clases

Definiciones de tipo. Sinónimos de tipo

Programación Funcional Haskell Clase 19

Tema 3: Tipos y clases

Tema 2: Introducción a la programación con Haskell

Tema 2: Introducción a la programación con Haskell

Tema 2: Introducción a la programación con Haskell

Tema 2: Introducción a la programación con Haskell

Para entender la recursividad primero tenemos que entender la recursividad

UNIDAD 2 Descripción de un programa

Tema 4: Definición de funciones

Tema 4: Definición de funciones

1.1 Define un operador ( ) que devuelva True si y solo si tan solo uno de sus argumentos es True. Por ejemplo:? (3 > 2) (2 > 5)

Introducción a OCaml. October 19, 2015

Tipos de datos y clases de tipos

Un calculadora avanzada... y algo más!

Algoritmos y programas. Algoritmos y Estructuras de Datos I

CAPÍTULO IV: 4.1 Introducción a la. Programación Funcional

Tipos en Haskell. Cecilia Manzino

Programación Declarativa. Ingeniería Informática Cuarto curso. Primer cuatrimestre. Escuela Politécnica Superior de Córdoba Universidad de Córdoba

Guardas y Tipos de datos

Comprender las diferencias entre tipos de datos primitivos similares, y aprender a elegir el tipo más conveniente en cada caso.

Elementos de un programa en C

El lenguaje Haskell 98

Programación Declarativa. Ingeniería Informática Cuarto curso. Primer cuatrimestre. Escuela Politécnica Superior de Córdoba Universidad de Córdoba

Informática General 2016 Cátedra: Valeria Drelichman, Pedro Paleo, Leonardo Nadel, Norma Morales

TEMA 2. LENGUAJE C. CONCEPTOS BÁSICOS Y PROGRAMACIÓN ELEMENTAL.

Tema 4. Funciones de orden superior

El lenguaje C. 1. Identificadores, constantes y variables

Tipos de datos algebraicos

Programación Declarativa

Ficha de Aprendizaje N 13

Principios de Computadoras II

Lenguajes de Inteligencia Artificial Segundo curso. Primer cuatrimestre

Introducción a la programación. Cecilia Manzino

Tema 2.- Expresiones y funciones

Informática General 2018 Cátedra: Valeria Drelichman, Pedro Paleo, Leonardo Nadel, Norma Morales

Programación Declarativa Haskell Informática Sistemas Curso Pepe Gallardo Universidad de Málaga. Tema 8. Listas

Datos Elementales y formato de un programa en Java

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Informática Haskell Matemáticas Curso Pepe Gallardo Universidad de Málaga. Tema 8. Listas

Componentes Básicos. InCo. InCo Componentes Básicos 1 / 28

FORMATO DEL FICHERO CON LA TABLA DE SÍMBOLOS

Tema 4. Funciones de orden superior

Tema 4. Operadores y Expresiones

Programación con listas. El tipo lista

abril de 2017 Desarrollo de aplicaciones en Java Tipos de datos primitivos Tipos de datos Elementos de aplicaciones simples

Tipos y Estructuras de Control. Dpto. de Ciencias e Ingeniería de la Computación UNIVERSIDAD NACIONAL DEL SUR

Tipos de Datos Simples Contenido del Tema

GUÍA DE TRABAJO N 1 C# Ing. Néstor Raúl Suarez Perpiñan Página 1 de 13

21/03/2018. Variables y Constantes. Los datos de un programa están representados por variables o constantes y tienen asociado un tipo.

TEMA 2. EL LENGUAJE C. ELEMENTOS BÁSICOS

Tema 8: Funciones de orden superior

Tema 8: Funciones de orden superior

INFOTECH MÓDULO 3 CURSO. Sintaxis del lenguaje de programación JAVA. Lógica y Lenguaje de Programación

4. Operadores Operador asignación

Tema 2: Desarrollo de Algoritmos. E.E. de Algorítmica

Tema 3.- Predicados y sentencias condicionales

Tema 9: Declaraciones de tipos y clases

Java. Introducción a la Programación Orientada a Objetos

Datos y tipos de datos

Tema 9: Declaraciones de tipos y clases

Los parámetros: son los campos que se comunican a los métodos de los objetos.

Instituto Tecnológico de Celaya

PHP: Lenguaje de programación

Laboratorio Análisis Lógico Práctica 2: Tipos de datos en Haskell

Metodologías de Programación II Introducción a OCaml

Tema 3. Tipos de datos simples

Lenguajes de Programación. Capítulo 4. Expresiones.

Introducción a la Programación

Índice del capítulo. Capítulo 4. Expresiones. Las expresiones. Indice de la sección. Lenguajes de Programación. Introducción. 2.

FUNDAMENTOS DE INFORMÁTICA

Informática de 1 o de Matemáticas. Ejercicios de Introducción a Haskell. Ejercicio 1 Consideremos la siguiente definición:

Transcripción:

El Lenguaje Haskell Tema 2: Introducción a Haskell A. Chávez-González 1 A. Riscos-Núñez 1 F. Sancho-Caparrini 1 1 Departamento de Ciencias de la Computación e Inteligencia Artificial Universidad de Sevilla http://www.cs.us.es/cursos/lp/ Lógica y Programación, 2006/07

Índice El Lenguaje Haskell 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El Lenguaje Haskell Características Haskell es un lenguaje funcional puro, no estricto y fuertemente tipificado. Puro: Transparencia referencial. Una expresión denota siempre el mismo valor, en cualquier punto del programa en que aparezca. Razonamiento ecuacional utilizado en matemáticas. No estricto: orden no aplicativo. Evaluación perezosa: Normalizante Trabajo mínimo Eficiente Trabajo con estructuras de datos infinitas Tipificación fuerte: elementos clasificados en categorías. Sistema de tipos estático: comprobación en la compilación Sistema de tipos polimórfico: más flexible Permite la sobrecarga: el mismo nombre Son aconsejables las anotaciones de tipo en los programas

El Lenguaje Haskell Un programa Haskell consiste en una o varias definiciones de funciones Ejemplo: Declaración: tipo Definición: método de cómputo -- Un ejemplo de fichero Haskell -- Calcula el siguiente entero al argumento sucesor :: Integer -> Integer sucesor x = x + 1 -- Calcula la suma de los cuadrados de sus argumentos sumacuadrados :: Integer -> Integer -> Integer sumacuadrados x y = x * x + y * y

Índice El Lenguaje Haskell 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El tipo Bool El Lenguaje Haskell Expresiones lógicas cuyo resultado puede ser verdadero o falso. Constructores: True, False Funciones y operadores: (&&) :: Bool -> Bool -> Bool ( ) :: Bool -> Bool -> Bool not :: Bool -> Bool otherwise :: Bool

El tipo Int El Lenguaje Haskell Números enteros de precisión limitada en el intervalo [ 2 29, 2 29 1 ] Funciones y operadores: (+)(-)(*) :: Int -> Int -> Int ( ) :: Int -> Int -> Int div, mod :: Int -> Int -> Int abs :: Int -> Int signum :: Int -> Int negate :: Int -> Int even, odd :: Int -> Bool Ejemplo: Podemos definir otras funciones a partir de ellas maximo :: Int -> Int -> Int maximo x y = div ((x + y) + abs(x - y)) 2

El Lenguaje Haskell El tipo Integer Los valores son enteros de precisión ilimitada que se usan cuando los números tratados se salen del rango de los valores del tipo Int El cálculo es menos eficiente Las operaciones disponibles son las mismas que para el tipo de datos Int

El tipo Float El Lenguaje Haskell Números reales. Notación: 1.35, -15.345, 1.0 ó 1 1.5e7, 1.5e - 17 Funciones y operadores: (+)(-)(*)(/) :: Float -> Float -> Float ( ) :: Float -> Int -> Float (**) :: Float -> Float -> Float abs :: Float -> Float signum :: Float -> Float (-1.0, 0.0, 1.0) negate :: Float -> Float sin, asin, cos, acos, tan, atan :: Float -> Float

El tipo Float El Lenguaje Haskell Funciones y operadores: atan2 :: Float -> Float -> Float log, exp :: Float -> Float sqrt :: Float -> Float pi :: Float trucate, round, floor, ceiling :: Float -> Float fromint :: Int -> Float frominteger :: Integer -> Float

El Lenguaje Haskell El tipo Double Números reales en un intervalo mayor que Float Más precisión (doble) Operaciones disponibles: las mismas que para Float

El tipo Char El Lenguaje Haskell Un valor tipo Char representa un carácter ( a, 1,? ) Caracteres especiales van precedidos por \ \n Salto de línea \t Tabulador \ Comilla \ Comilla doble \ El carácter \ Funciones: ord :: Char -> Int chr :: Int -> Char isupper, islower, isdigit, isalfa :: Char -> Bool toupper, tolower :: Char -> Char

El tipo Char El Lenguaje Haskell Ejemplos: Prelude> toupper a A :: Char Prelude> isupper a False :: Bool Prelude> ord a 97 :: Int Prelude> chr 98 b :: Char

El Lenguaje Haskell de igualdad y orden Para todos los tipos básicos están definidos los operadores binarios que devuelven un valor booleano: (<) mayor que ( ) mayor o igual que (<) menor que ( ) menor o igual que (==) igual que ( ) distinto de

El Lenguaje Haskell de igualdad y orden El tipo de los dos argumentos debe ser el mismo Prelude> 10 15 Prelude> b > a True :: Bool True :: Bool Prelude> x == y Prelude> False < True False :: Bool True :: Bool Prelude> x y Prelude> (1 < 5) && (10 > 9) True :: Bool True :: Bool Prelude> True < a ERROR : Type error in application *** Expression : True < a *** Term : True *** Type : Bool *** Does not match : Char

El Lenguaje Haskell de igualdad y orden Orden para el tipo Char: mayúsculas son menores que minúsculas. Dentro de cada grupo se mantiene el orden alfabético. Orden para el tipo Bool: False menor que True (==) es el símbolo de igualdad, = se reserva para definir funciones Para todos los tipos que definen un orden, están definidas las funciones max y min

Índice El Lenguaje Haskell 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El Lenguaje Haskell Además de los tipos simples, Haskell define tipos estructurados que permiten representar colecciones de objetos. Tuplas Una tupla es un dato compuesto donde cada componente puede ser de un tipo diferente Si v 1, v 2,..., v n son valores con tipo t 1, t 2,..., t n, entonces (v 1, v 2,..., v n )es una tupla con tipo (t 1, t 2,..., t n ) Ejemplos: Prelude> ( a, True, 1.5) ( a, True, 1.5) :: (Char, Bool, Double) Útiles cuando una función tiene que devolver más de un valor predsuc :: Integer -> (Integer, Integer) predsuc = (x - 1, x + 1)

El Lenguaje Haskell Listas Una lista es una colección de cero o más elementos todos del mismo tipo. Hay dos constructores u operadores para construir valores para listas: [] Lista vacía (:) Añade un elemento al princicipo de una lista. Si v 1, v 2,..., v n son valores con tipo t, entonces v 1 : (v 2 : (... (v n 1 : (v n : []))... )) es una lista con tipo [t] Ejemplos: 1 : [] Lista que almacena un único entero; tipo [Integer] 3 : (1 : []) Lista que almacena dos enteros; primero el 3 y luego el 1; tipo [Integer] a : (1 : []) Error de tipo

El Lenguaje Haskell Listas Una lista es una colección de cero o más elementos todos del mismo tipo. Hay dos constructores u operadores para construir valores para listas: [] Lista vacía (:) Añade un elemento al princicipo de una lista. Si v 1, v 2,..., v n son valores con tipo t, entonces v 1 : (v 2 : (... (v n 1 : (v n : []))... )) es una lista con tipo [t] Ejemplos: 1 : [] Lista que almacena un único entero; tipo [Integer] 3 : (1 : []) Lista que almacena dos enteros; primero el 3 y luego el 1; tipo [Integer] a : (1 : []) Error de tipo

El Lenguaje Haskell Listas Asociatividad a la derecha del operador (:). La lista x 1 : x 2 : : x n 1 : x n : [] representará x 1 : (x 2 : ( : (x n 1 : (x n : []))... )) Haskell permite una sintaxis más cómoda [x 1, x 2,..., x n 1, x n ] Ejemplos: Prelude> 1:(2:(3:[])) [1,2,3] :: [Integer] Prelude> 1:2:3:[] [1,2,3] :: [Integer] Prelude> [1,2,3] [1,2,3] :: [Integer]

El Lenguaje Haskell Listas Asociatividad a la derecha del operador (:). La lista x 1 : x 2 : : x n 1 : x n : [] representará x 1 : (x 2 : ( : (x n 1 : (x n : []))... )) Haskell permite una sintaxis más cómoda [x 1, x 2,..., x n 1, x n ] Ejemplos: Prelude> 1:(2:(3:[])) [1,2,3] :: [Integer] Prelude> 1:2:3:[] [1,2,3] :: [Integer] Prelude> [1,2,3] [1,2,3] :: [Integer]

El Lenguaje Haskell Cadenas de caracteres Una cadena de caracteres es una secuencia de cero o más caracteres. Lista de caracteres x 1 x 2... x n 1 x n representa [ x 1, x 2,..., x n 1, x n] Ejemplos: Prelude> [ U, n,, C, o, c, h, e ] Un Coche :: [Char] Prelude> Un Coche Un Coche :: String Prelude> U : n : : C : o : c : h : e :[] Un Coche :: [Char]

El Lenguaje Haskell Cadenas de caracteres Una cadena de caracteres es una secuencia de cero o más caracteres. Lista de caracteres x 1 x 2... x n 1 x n representa [ x 1, x 2,..., x n 1, x n] Ejemplos: Prelude> [ U, n,, C, o, c, h, e ] Un Coche :: [Char] Prelude> Un Coche Un Coche :: String Prelude> U : n : : C : o : c : h : e :[] Un Coche :: [Char]

El Lenguaje Haskell El constructor de tipo ( ) Para declarar el tipo correspondiente a las funciones. Si t 1, t 2,..., t n, t r son tipos válidos, entonces t 1 t 2 t n t r es el tipo de una función con n argumentos Ejemplo: inc :: Integer -> Integer inc x = x + 1

El Lenguaje Haskell El constructor de tipo ( ) Para declarar el tipo correspondiente a las funciones. Si t 1, t 2,..., t n, t r son tipos válidos, entonces t 1 t 2 t n t r es el tipo de una función con n argumentos Ejemplo: inc :: Integer -> Integer inc x = x + 1

El Lenguaje Haskell El constructor de tipo ( ) Funciones como argumento o resultado. Funciones que devuelven otra función (orden superior): componer :: (Int -> Int) -> (Int -> Int) -> Int -> Int componer f g x = g (f x) No pueden eliminarse los paréntesis componer inc inc 10 = sustituyendo en la definición de componer inc(inc10) = por la definición de inc (inc10) + 1 = por la definición de inc (10 + 1) + 1, por la definición de (+): 11 + 1, y de nuevo por la definición de (+): 12

Índice El Lenguaje Haskell 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El Lenguaje Haskell Insertar comentarios Dos modos de incluir comentarios (texto ignorado por el evaluador) en un programa: de una sola ĺınea: comienzan por dos guiones consecutivos ( ) y abarcan hasta el final de la ĺınea actual: f :: Integer -> Integer f x = x + 1 -- Esto es un comentario de más de una ĺınea: comienzan por los caracteres {- y acaban con -} {- Esto es un comentario de más de una línea -} g :: Integer -> Integer g x = x - 1

Índice El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad son funciones binarias cuyo nombre es simbólico (cadena de signos, no letras) Pueden ser invocados de forma infija Hay operadores predefinidos como &&,, +,,, /y Podemos definir nuevos operadores utilizando uno o más de los siguientes símbolos: :! #$%& + / <=>?@\ sólo una vez y al principio. Solo es reservado Los operadores que comienzan por (:) tienen un significado especial, constructores infijos de datos Ejemplos de operadores: + + + && == // $ predefinidos @@ % + < + >? Reservados: :: :.. = @ \

Cláusulas Infix El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Al definir un nuevo operador podemos indicar su prioridad (0 a 9) y su asociatividad infix [prioridad] [identificador] No asociativo infixl [prioridad] [identificador] Asociativo a izda. infixr [prioridad] [identificador] Asociativo a dcha. Ejemplo de definición de operador infix 4 = -- Prioridad 4, no asociativa ( =) :: Float -> Float -> Bool -- Tipo x = y = abs (x - y) < 0.0001 -- Definición Obligatorio escribirlo entre paréntesis en la declaración de tipo Puede usarse de modo infijo Main> 1.0 = 2.0 Main> 1.0 = 1.00001 False :: Bool True :: Bool

Prioridades El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Ante prioridades distintas, se agrupan en primer lugar los de mayor prioridad, en ausencia de paréntesis Ejemplo: La expresión 1 + 2 4 se interpreta como 1 + (2 4) ya que ( ) tiene mayor prioridad (7) que (+) (6) Si se desea otra interpretación, se pueden utilizar paréntesis: (1 + 2) 4 La llamada a una función tiene prioridad máxima (10) La prioridad no aclara qué ocurre cuando un mismo operador aparece varias veces en una expresión: 8 5 1 puede ser intepretado como ((8 5) 1) ó (8 (5 1)). La asociatividad indica que la primera opción es la correcta

El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Asociatividades Si un operador es asociativo a la izquierda: x 1 x 2 x n 1 x n = (... (x 1 x 2 ) x n 1 ) x n Si un operador es asociativo a la derecha: x 1 x 2 x n 1 x n = x 1 (x 2 (x n 1 x n )... )

El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Asociatividades Si un operador es asociativo a la izquierda: x 1 x 2 x n 1 x n = (... (x 1 x 2 ) x n 1 ) x n Si un operador es asociativo a la derecha: x 1 x 2 x n 1 x n = x 1 (x 2 (x n 1 x n )... )

El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Si un operador es no asociativo, no puede utilizarse más de una vez sin aclarar el significado con paréntesis Ejemplos: infix 7 ( ) :: Integer -> Integer x y = div x y Main> 7 4 2 ERROR: Ambiguous use of operator with Main> (7 4) 2 0 :: Integer Main> 1 < 2 == True ERROR: Ambiguous use of operator < with == En Haskell, todo operador no declarado con cláusulas infix, toma por defecto prioridad 9 y asociatividad izquierda.

El Lenguaje Haskell predefinidos su definición Prioridad y Asociatividad Tabla de Prioridad y Asociatividad de los operadores predefinidos infixr 9 infixl 9!! infixr 8,, infixl 7, /, quot, rem, div, mod infixl 6 +, - infixr 5 :, ++ infix 4 ==,, <,,, >, elem, notelem infixr 3 && infixr 2 infixl 1, = infixr 1 = infixr 0 $, $!, seq

El Lenguaje Haskell frente a funciones predefinidos su definición Prioridad y Asociatividad Cualquier operador puede usarse de modo prefijo o infijo, independientemente de como esté declarado infix 4 = ( =) :: Float -> Float -> Bool ( =) x y = abs (x - y) < 0.0001 Toda función puede convertirse en un operador si se escribe entre acentos franceses: suma :: Integer -> Integer -> Integer suma x y = x + y x suma y = x + y Main> suma 1 2 Main> 1 suma 2 Se puede dar prioridad y asociatividad al uso infijo de cualquier función: infixl 6 suma

Índice El Lenguaje Haskell Patrones y otros tipos de Expresiones 1 El lenguaje Haskell 2 simples predefinidos 3 predefinidos 4 5 predefinidos su definición Prioridad y Asociatividad de los operadores 6 Patrones y otros tipos de Expresiones

El Lenguaje Haskell Comparación de patrones Patrones y otros tipos de Expresiones En Haskell los parámetros formales de una función no sólo pueden ser nombres de variables, un argumento puede ser un patrón (una expresión) Es posible definir una función dando más de una ecuación para ésta. Cada ecuación definirá el comportamiento de la función para distintas formas del argumento. Los patrones capturan dicha forma Al aplicar una función a un parámetro concreto la comparación de patrones determina la ecuación a utilizar

Patrones constantes El Lenguaje Haskell Patrones y otros tipos de Expresiones Un patrón constante puede ser un número, un carácter o un constructor de datos. f :: Integer -> Bool = True f 2 = False Main> f 1 True :: Bool Main> f 3 Program error: f 3

Patrones constantes El Lenguaje Haskell Patrones y otros tipos de Expresiones La función está parcialmente definida. Si queremos definirla totalmente, añadimos otra ecuación: f :: Integer -> Integer f 1 = True f 2 = False -- Tercera línea f x = True Atención al orden. Y si apareciera f 1 False en la tercera ĺınea?

Patrones constantes El Lenguaje Haskell Patrones y otros tipos de Expresiones Con un patrón constante sólo unifica un argumento que coincida con esa constante Cuando la función tiene más de un argumento: Se comprueban los patrones correspondientes a las distintas ecuaciones en el orden dado por el programa, hasta que se encuentre una que coincida Dentro de una misma ecuación se intentan unificar los patrones correspondientes a los argumentos de izquierda a derecha Cuando un patrón falla para un argumento, se pasa a la siguiente ecuación La función que se está definiendo puede aparecer como parte de la expresión resultado: RECURSIVIDAD El uso de patrones y recursividad permite definiciones compactas y elegantes

Recursividad El Lenguaje Haskell Patrones y otros tipos de Expresiones Ejemplo: fact :: Integer -> Integer fact 0 = 1 fact n = n * fact(n - 1) Para que una definición recursiva sea efectiva hay que garantizar que: Exista un caso no recursivo, al menos. Caso base. En el ejemplo, fact0 En cada llamada recursiva, el valor del argumento se acerca al caso base El caso base se alcanza, es decir, la reducción acaba. Como en el ejemplo.

Recursividad El Lenguaje Haskell Patrones y otros tipos de Expresiones Si una de estas condiciones falla, la reducción no terminará: fact :: Integer -> Integer fact 0 = 1 fact n = n * (n - 1) * fact (n - 2) -- Falla la tercera condición. -- No termina para impares

Patrones para listas El Lenguaje Haskell Patrones y otros tipos de Expresiones Los patrones que se usan al definir funciones que trabajen con listas toman las siguientes formas: [] Sólo unifica con un argumento que sea una lista vacía [x], [x, y], etc. sólo unifican con listas de uno, dos, etc. argumentos (x : xs) unifica con listas con al menos un elemento (x : y : zs) unifica con listas con al menos dos elementos... suma :: [Integer] -> Integer suma [] = 0 -- Caso base suma (x:xs) = x + suma xs -- Caso recursivo

Patrones para tuplas El Lenguaje Haskell Patrones y otros tipos de Expresiones Puede usarse la sintaxis de tuplas en patrones primero2 :: (Integer, Integer) -> Integer primero2 (x, y) = x -- Primero para pares primero3 :: (Integer, Integer, Integer) -> Integer primero3 (x, y, z) = x -- Primero para ternas Los patrones pueden anidarse sumapares :: [(Integer, Integer)] -> Integer sumapares [] = 0 sumapares ((x, y):xs) = x + y + sumapares xs

Patrones aritméticos El Lenguaje Haskell Patrones y otros tipos de Expresiones Un patrón aritmético es de la forma (n + k), donde k es un número natural factorial :: Integer -> Integer factorial 0 = 1 factorial (n + 1) = (n + 1) * factorial n

El Lenguaje Haskell Patrones nombrados o Seudónimos Patrones y otros tipos de Expresiones Un patrón seudónimo o patrón alias sirve para nombrar un patrón utilizar el seudónimo en vez del patrón en la parte derecha de la definición factorial :: Integer -> Integer factorial 0 = 1 factorial m@(n + 1) = m * factorial n El cualificador @ en la segunda ecuación asigna el seudónimo m al patrón (n + 1)

Patrón subrayado El Lenguaje Haskell Patrones y otros tipos de Expresiones Un patrón subrayado ( ) unifica con cualquier argumento pero no establece ninguna ligadura longitud :: [Integer] -> Integer longitud [] = 0 longitud ( :xs) = 1 + longitud xs

El Lenguaje Haskell Patrones y evaluación perezosa Patrones y otros tipos de Expresiones La unificación determina qué ecuación es seleccionada para reducir una expresión a partir de la forma de los argumentos esvacía :: [a] -> Bool esvacía [] = True esvacía ( : ) = False Para poder reducir una expresión como esvacía l es necesario saber si l es una lista vacía o no Haskell evalúa un argumento hasta obtener un número de constructores suficiente para resolver el patrón, sin obtener necesariamente su forma normal infinita :: [Integer] esvacía infinita infinita = 1: infinita = esvacía (1: infinita) False

Expresiones case El Lenguaje Haskell Patrones y otros tipos de Expresiones La sintaxis de esta construcción es: case expr of patron 1 resultado 1 patron 2 resultado 2... patron n resultado n Todos los patrones son del mismo tipo (el mismo que el de expr) Todos los resultados deben ser del mismo tipo, el tipo del resultado Ejemplo: long :: [Integer] -> Integer long ls = case ls of [] 0 :xs 1 + long xs

La función error El Lenguaje Haskell Patrones y otros tipos de Expresiones Permite controlar casos sin sentido en funciones parciales y generar un mensaje de error cabeza :: [Integer] -> Integer cabeza [] = error lista vacía cabeza (x: ) = x Main> cabeza [1, 2, 3] 1 :: Integer Main> cabeza [] Program error: lista vacía

El Lenguaje Haskell Funciones a trozos (por partes) Patrones y otros tipos de Expresiones En ellas el resultado depende de cierta condición absoluto :: Integer -> Integer absoluto x x 0 = x x < 0 = -x El sangrado es obligatorio (con el tabulador, no espacios) Guardas, son de tipo Bool Se evalúan las guardas en el orden textual hasta encontrar un valor True, en cuyo caso se devuelve la expresión a la derecha de dicha guarda Puede usarse como guarda otherwise, que equivale a True

El Lenguaje Haskell Expresiones condicionales Patrones y otros tipos de Expresiones Otro modo de escribir expresiones cuyo resultado depende de cierta condición: if exprbool then exprsi else exprno Funcionamiento: Se evalúa exprbool, de tipo Bool Si el valor es True, devuelve exprno En otro caso, exprsi Los tipos de ambos resultados deben coincidir Al ser perezoso, no se evalúa más que el resultado que se devuelve Es válida la expresión 2 if a < z then 10 else 4

El Lenguaje Haskell Expresiones condicionales Patrones y otros tipos de Expresiones Ejemplo: maxent :: Integer -> Integer -> Integer maxent x y = if x y then x else y

Definiciones locales El Lenguaje Haskell Patrones y otros tipos de Expresiones Nombrando subexpresiones: raices :: Float Float Float (Float, Float) raices a b c b 2 4 a c 0 = (( b + sqrt(b 2 4 a c))/(2 a), ( b sqrt(b 2 4 a c))/(2 a)) otherwise = error raices complejas

Definiciones locales El Lenguaje Haskell Patrones y otros tipos de Expresiones raices :: Float Float Float (Float, Float) raices a b c disc 0 = (( b + raizdisc)/denom, ( b raizdisc)/denom) otherwise = error raices complejas where disc = b 2 4 a c raizdisc = sqrt disc denom = 2 a Las definiciones locales where solo pueden aparecer a final de una definición de función

Definiciones locales El Lenguaje Haskell Patrones y otros tipos de Expresiones Para introducir definiciones locales en cualquier parte de una expresión se usa let e in. Prelude> let f n = n 2 + 2 in f 100 10002 :: Integer

Expresiones lambda El Lenguaje Haskell Patrones y otros tipos de Expresiones Haskell permite definir funciones anónimas Ejemplo: λ x x + 1 Con un argumento: Prelude> :t λ x -> isupper x λ x -> isupper x :: Char -> Bool Con más de un argumento: Prelude> :t λ x y -> isupper x && isupper y λ x y -> isupper x && isupper y :: Char -> Char -> Bool Prelude> (λ x y -> isupper x && isupper y) A z False :: Bool

Sangrado El Lenguaje Haskell Patrones y otros tipos de Expresiones Cuándo acaba una definición Definiciones globales Definiciones locales introducidas por where, let Alternativa al layout: llaves y ; h x y = let {dob n = 2 * n; tri n = 3 * n}in dob x + tri y

Ámbitos y módulos El Lenguaje Haskell Patrones y otros tipos de Expresiones Reglas de ámbitos f :: Integer -> Integer f x = x * h 7 where h z = x + 5 + z ^ 2 (+++) :: Integer -> Integer -> Integer a +++ b = 2 * a + f b import