Capitulo 4 Introducción a Haskell Es un software libre, fácil de obtener y de instalar, y que además tiene muchísimo material de lectura para descarga gratuita en Internet. Es por estos motivos que fue elegido en este profesorado. Si el interés del lector es saber “todo” sobre Haskell, puede dirigirse directamente al sitio web www.haskell.org Hay también mucho sitios en español. Claro, para saber “todo” sobre Haskell se puede entrar en los 30 millones de sitios web que tratan el tema, o en el millón de sitios en español. Para leer los sitios en español demoraría más de 2500 años, si cada sitio lo leyera en un día....... Entonces lo mejor es no ponerse ansioso y leer este capítulo tranquilamente, que lo irá conduciendo a los fundamentos de lo que tiene que saber. Subyace, entonces, la idea de que lo más importante es aprender a aprender, para que, una vez egresado, pueda dedicarse y especializarse en los temas que prefiera. Instalación de Haskell. Descargar el instalador desde www.haskell.org Prestar atención al sistema operativo que utiliza su computadora. Luego de instalado, pruébelo!! Si puede digitar 2 + 5 y le da 7, felicitaciones !!! Primeros pasos con Haskell. Este software vamos a usarlo a lo largo de todo el año. Necesitamos empezar a familiarizarnos con él. Como práctica individual, se puede empezar utilizando Haskell como calculadora, haciendo las operaciones del práctico 4. Las operaciones comunes funcionan bien. Pruébelas. Veamos un avance. Luego de instalado el programa, en la primer pantalla que aparece, llamada "línea de comandos", si escribimos 2+5 y digitamos enter, debería aparecer un "7". En la versión de Haskell 98 , utilizando Hugs como intérprete por defecto, se verá así: En la versión 2012 se ve así: Funciones predefinidas. Existen funciones especiales que ya vienen cargadas en Hugs. Algunas son completamente nuevas y seguramente no las ha utilizado el estudiante antes. div a b : el cociente de la división entera entre a y b. El cociente de la división entera entre 33 y 7 es 4. Aquí se llama div. div 33 7 = 4 Observe que no lleva paréntesis. Sólo un espacio. La función div espera 2 números enteros y su respuesta es otro número entero. Adelantándonos un poco al tema de funciones, el dominio de esta función parecería que es un par ordenado de números enteros y el codominio es otro número entero. ¿Siempre se puede hacer la división entre a y b, para cualquier a y b enteros? Respuesta: NO. 5 dividido 0 no se puede hacer. ¿Porque ? Vamos a explicarlo. Primero, un ejemplito: 14 dividido 7 es 2 porque 7 * 2 = 14 Si 5 dividido 0 fuera un número n, entonces n * 0 tendría que dar 5, lo que es imposible. Da 0. div : ] x ]* → ] Esto significa que la función "div" tiene por dominio un par ordenado de números enteros, en el cual el primer elemento es un número entero, cualquiera, y el segundo elemento es un número entero diferente de cero. Además el codominio es un número entero. Al conjunto de los números enteros lo representamos con la Z. * Z es el conjunto de los enteros sin el cero. El orden es muy importante, entonces. div 7 33 = 0 porque 7 dividido 33 da cociente cero. Por otra parte, como ya lo dijimos antes, la función div espera 2 números, el dividendo y divisor. ¿Cual es el cociente de dividir 33 entre.....? La respuesta es: "no se , aca falta algo" ¿Cual es el cociente de dividir ..... entre 7 ? La respuesta también es: "no se , aca también falta algo" Entonces no se extrañe, querido lector, si al digitar div 33 el programa le da un aviso de error. Por supuesto que también le dará aviso de error si digita div 33 4 6. Hay demasiados parámetros. mod a b : el resto de dividir a entre b mod 33 7 = 5 mod 7 33 = 7 Ejercicio 1: ¿Que espera obtener si digitamos mod 19 3 ? ¿Y si digitamos mod (-19) 3 ? (Observación: los números negativos necesitan paréntesis en Haskell) Luego de su sorpresa, piense !!!!! Recuerde que en la definición de división entera es fundamental que el resto de la división entera siempre sea menor que el divisor y además positivo. División entera entre a y b: definición: Sean a y b números enteros, con b positivo. Dividir a entre b significa encontrar dos números enteros q y r de modo que se verifique: Vamos a dividir (-19) entre 3. Como aún no tenemos experiencia en hacer estas divisiones, podemos probar un poco para investigar. Tenemos varias opciones: En los tres casos se cumple que -19 = 3.q + r , pero sólo en uno el resto es positivo y menor que 3. Pruebe ahora, estimado lector, investigar que responde su ordenador al digitar: div (-19) 3 mod (-19) 3 Funciones lógicas : ││ (or) && (and) == (igual) Las funciones lógicas devuelven, esto es, tienen como codiminio, un elemento del conjunto Bool. El conjunto Bool es un un conjunto que tiene solamente 2 elementos: Verdadero y Falso. Es muy común que usemos esas palabras en inglés. Entonces Bool = {True, False} Por ejemplo, nos preguntamos si 8 será mayor que 5. La respuesta es si, por supuesto. En haskell se escribe así: 8>5 Al dar “enter” la respuesta es True. Otro ejemplo: (8 > 5) && (3 > 7) Aca tenemos el and lógico, el y lógico. En este caso el primer paréntesis se cumple pero el segundo no. La respuesta es False. Tambien nos podremos preguntar si el resto de dividir 9 entre 2 será 0. mod 9 2 == 0 (cuidado que hay 2 signos de = pegaditos. No se puede dejar espacio entre ellos) La respuesta es False. En resumen: mod 9 2 tiene como respuesta 1 (es el resto de la división entera de 9 entre 2) mod 9 2 ==1 tiene respuesta True. (pregunta ¿el resto de la división entera de 9 entre 2 es 1? ) mod 9 2 ==0 tiene respuesta False. (pregunta ¿el resto de la división entera de 9 entre 2 es 0? ) Hay más funciones lógicas predefinidas en Hugs.Por ejemplo /= distinto , not (negación). PRÁCTICO 4 Introducción a Haskell 1) Escriba en la linea de comandos de Hugs, de a una, las siguientes expresiones. Presione la tecla Enter. ¿Obtiene el resultado esperado? a) 2+5 b) 2^10 c) 3*(5+4) d) 2^(6+1) e) 8/3 f) mod 18 5 g) mod 19 5 h) mod 20 5 i) div 20 5 j) div 21 5 k) div (-21) 5 l) mod (-21) 5 2) Escriba y ejecute las siguientes expresiones en Hugs. Deduzca su comportamiento. a) max 5 9 b) min 5 8 c) max 5 (max 3 7) d) (7>3) e) (7>3) || (3>5) f) (7>3) && (3>5) g) 2+5 == 7 h) 2+5 == 8 i) mod 15 4 == 1 j) 5 /= 1+4 k) not (mod 7 3 == 1) l) mod 12 5 == 3 m) mod 12 5 <= 3 Siga investigando. Invente sus propias expresiones booleanas en Hugs y evalúelas. 3) En Haskell hay varias clases de datos, llamadas tipos. En el tipo Integer se encuentran los números enteros. En el tipo Int se encuentran los números enteros dentro de cierto rango. Se utiliza el tipo Int porque, aunque sus resultados podrían estar afectados de error si sobrepasamos el máximo o el mínimo del rango, existe la ventaja de la mayor rapidez de los cálculos y de la menor utilización de memoria. Para los cálculos comunes, el tipo Int es más que suficiente. Para indicarle al software que queremos una operación con un tipo determinado, utilizamos :: Por ejemplo, si queremos hacer 2^5 utilizando Integer, lo indicamos asi 2^5::Int 2^5::Integer en este caso le estamos pidiendo que utilice el tipo Int. "Por ahora" da lo mismo. Realizar los siguientes cálculos en Hugs: a) 2^30::Integer 2^30::Int 2^31-1::Integer 2^31-1::Int 2^31::Integer 2^31::Int ¿Cuál será, entonces, el límite máximo de utilización del tipo Int ? Prueba ahora los comandos minBound::Int y maxBound::Int 4) Tipos en Haskell: para conocer el tipo de una expresión, existe el comando :type Investiga que sucede al escribir lo siguiente: :type "palabra" :type 'a' :type True :type 4<5 :type ("casa", 'a') :type (23,"uno", '3') 5) Investiga un poco más. fst (5,7) snd (5,7) fst ("yo",5) Indicar el tipo de las funciones fst, snd y length length "zapato"