Herramientas de usuario

Herramientas del sitio


introalg:taller08_1

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
introalg:taller08_1 [2008/03/18 21:17] lauraintroalg:taller08_1 [2018/08/10 03:03] (actual) – editor externo 127.0.0.1
Línea 5: Línea 5:
 ===== Introducción al uso de Hugs===== ===== Introducción al uso de Hugs=====
  
-[[http://haskell.org/hugs/|Hugs]] es un intérprete del lenguaje funcional puro [[http://haskell.org/|Haskell]]. \\ +[[http://haskell.org/hugs/|Hugs]] es un intérprete del lenguaje funcional puro [[http://haskell.org/|Haskell]]. 
-Durante este taller escribiremos, probaremos y utilizaremos los programas funcionales que se dan en el teórico.+ 
 +Durante este taller escribiremos, probaremos y utilizaremos programas funcionales.
  
 A Hugs se lo invoca desde la //línea de comandos// o picando sobre el icono en nuestro entorno gráfico. A Hugs se lo invoca desde la //línea de comandos// o picando sobre el icono en nuestro entorno gráfico.
 Una vez que el intérprete está activo, la pantalla se presenta con un //prompt// a la espera de **expresiones** a ser evaluadas o **comandos**. Una vez que el intérprete está activo, la pantalla se presenta con un //prompt// a la espera de **expresiones** a ser evaluadas o **comandos**.
  
-  [nicolasw@azul Taller]$ hugs+  [laura@azul Taller]$ hugs
   __   __ __  __  ____   ___      _________________________________________   __   __ __  __  ____   ___      _________________________________________
   ||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard   ||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard
Línea 24: Línea 25:
   Hugs.Base>   Hugs.Base>
  
-De este modo Hugs se convierte en una calculadora, esperando que se introduzca una expresión para evaluarla e imprimir el resultado, y luego volver a pedir una expresión (lazo **leer-evaluar-imprimir**). \\ +De este modo Hugs se convierte en una calculadora, esperando que se introduzca una expresión para evaluarla e imprimir el resultado (lazo **leer-evaluar-imprimir**). Después, nuestra calculadora Hugs queda lista para volver a pedir una expresión.  
-Gracias al [[http://www.haskell.org/onlinereport/standard-prelude.html | preludio standard]] tenemos muchas funciones ya definidas.+ 
 +Gracias al [[http://www.haskell.org/onlinereport/standard-prelude.html | preludio estándar]] tenemos muchas funciones ya definidas, entre ellas, todas las aritméticas y las lógicas básicas. Pero también tenemos otras muchas, como por ejemplo "reverse".
  
   Hugs.Base> 21+21   Hugs.Base> 21+21
Línea 38: Línea 40:
   "daba le arroz al a zorra elabad"   "daba le arroz al a zorra elabad"
  
-Este ciclo continúa indefinidamente hasta que pidamos la salida del intérprete con ''CTRL-D'' o con el comando+Podemos salir del intérprete Hugs con ''CTRL-D'' o con el comando ":q".
  
   Hugs.Base> :q   Hugs.Base> :q
   [Leaving Hugs]   [Leaving Hugs]
-  [nicolasw@azul Taller]$+  [laura@azul Taller]$
  
 +Así volvemos al modo normal de la computadora.
  
  
-Para poder dar nuevas definiciones y/o funciones necesitamos escribir un //programa funcional// o //script// Haskell. \\ +Para poder dar nuevas definiciones y/o funciones, además de las que se encuentran en el [[http://www.haskell.org/onlinereport/standard-prelude.html | preludio estándar]], necesitamos escribir un //programa funcional// o //script// Haskell. 
 Un programa funcional es un [[http://es.wikipedia.org/wiki/Archivo_inform%C3%A1tico|archivo]] con terminación **''.hs''** donde se escriben en //texto plano// todas las definiciones que conforman el programa funcional. Un programa funcional es un [[http://es.wikipedia.org/wiki/Archivo_inform%C3%A1tico|archivo]] con terminación **''.hs''** donde se escriben en //texto plano// todas las definiciones que conforman el programa funcional.
  
-A manera de ejemplo realicemos un ciclo de **creación-carga-prueba-modificación-recarga**, con el Ejercicio 8.3 del apunte [[http://cs.famaf.unc.edu.ar/introalg/calculo_extracto.pdf|Extracto del Cálculo de Programas]].+Como ejemplo, vamos a ver todo el proceso de **creación-carga-prueba-modificación-recarga**, con el Ejercicio 8.3 del apunte [[http://cs.famaf.unc.edu.ar/introalg/calculo_extracto.pdf|Extracto del Cálculo de Programas]]
 + 
 +  sgn :: Int → Int  
 +  -- dado un entero x, //sgn// retorna su signo, de la siguiente forma:  
 +  -- retornará 1 si x es positivo, -1 si es negativo y 0 en cualquier otro caso. 
 + 
 +Para crear un //script// basta con invocar el comando para editar un (nuevo) archivo '':e cap8.hs''. También se puede crear el script mediante un editor de texto cualquiera (//emacs//, //bloc de notas//, //kate//, //vi//,...). 
 + 
 +  Hugs.Base> :e cap8.hs
  
-Para crear un //script// basta con invocar el comando para editar un (nuevo) archivo '':e cap8.hs''. 
 Una posible solución para el problema de la función signo es la siguiente: Una posible solución para el problema de la función signo es la siguiente:
  
Línea 60: Línea 71:
  
  
-Luego de salvar el programa cargarloel intérprete indica un error pues ''='' es el símbolo de definición, mientras que la comparación es ''==''.+Luego de guardar el programa, hay cargarlo para que el intérprete Hugs pueda empezar a usar la nueva función que hemos creado.
  
-  Hugs.Base> :e cap8.hs 
   Hugs.Base> :l cap8.hs   Hugs.Base> :l cap8.hs
   ERROR "cap8.hs":4 - Syntax error in input (unexpected `=')   ERROR "cap8.hs":4 - Syntax error in input (unexpected `=')
  
-Las traducciones son más o menos directas, de todas formas preparamos una tabla de [[http://cs.famaf.unc.edu.ar/introalg/PDF/traduccion.pdf|Traducción de "Cálculo de Programas" a Haskell]].+Pero el intérprete indica un error! Por qué? Porque "=" es el símbolo de definición, mientras que la comparación es "=="
 + 
 +Las traducciones de los símbolos son más o menos directas, de todas formas preparamos una tabla de [[http://cs.famaf.unc.edu.ar/introalg/PDF/traduccion.pdf|Traducción de "Cálculo de Programas" a Haskell]]
 + 
 +Para solucionar el error, volvemos a editar el script con '':e'' (el nombre ya no lo necesitamos ya que tenemos cargado este script) y corregimos ''x=0'' por ''x==0''
 + 
 +  sgn :: Int -> Int 
 +  sgn x   | 0<  = 1 
 +          | x<  = -1 
 +          | x==0  = 0 
 + 
 + 
 +Luego de guardar el programa, hay que **volver a cargarlo** para que el intérprete pueda usar la función corregida, si no lo cargamos, el intérprete se queda en el estado anterior, en el que no tenía la función porque ésta tenía un error. 
 + 
 +  Hugs.Base> :l cap8.hs 
 +  Main> 
 + 
 +Ahora sí, la función es correcta y por ello el intérprete nos muestra el prompt ''Main'', que indica que hemos cargado alguna función más de las que hay en el preludio estándar, y que las funciones que hemos cargado son correctas.
  
-Volvemos a editar el script con '':e'' (el nombre ya no lo necesitamos ya que tenemos cargado este script) y corregimos ''x=0'' por ''x==0''. \\ 
 Podemos probar la nueva función con //casos de test// para ganar confianza en su **corrección**. Podemos probar la nueva función con //casos de test// para ganar confianza en su **corrección**.
  
Línea 110: Línea 136:
   * Precedencia (''sgn -1'')   * Precedencia (''sgn -1'')
   * Tipos (''sgn 1.1'')   * Tipos (''sgn 1.1'')
-  * Sintáxis (''sgn (-1'')+  * Sintaxis (''sgn (-1'')
  
  
 ===== Inferencia de tipos ===== ===== Inferencia de tipos =====
  
-Hugs tiene una maquinaria para //inferir// tipos, tanto los declarados+Haskell es un lenguaje tipado, es decir, todos los datos pertenecen a una clase o tipo de datos. Hugs tiene una maquinaria para //inferir// tipos, tanto los declarados
  
   Main> :t sgn   Main> :t sgn
Línea 144: Línea 170:
  
 Esta maquinaria **impide** que escribamos cualquier expresión que esté mal tipada.   Esta maquinaria **impide** que escribamos cualquier expresión que esté mal tipada.  
 +
 +Todas las funciones suelen ir encabezadas por su signatura, es decir, el nombre de la función junto al tipo de sus parámetros y resultado. El nombre va seguido de ''::'' y los parámetros y el resultado van separados por ''->''. Por ejemplo:
 +
 +  sgn :: Int -> Int
 +  reverse :: [a] -> [a]
 +  map :: (a -> b) -> [a] -> [b]
  
  
 ===== Tuplas ===== ===== Tuplas =====
  
-Haskell maneja n-uplas de manera directa.+Haskell maneja n-uplas de manera directa. Las n-uplas nos permiten agrupar datos para manejarlos como una sola cosa, como veremos más adelante. 
 Incorporamos a ''cap8.hs'' las siguientes definiciones: Incorporamos a ''cap8.hs'' las siguientes definiciones:
  
Línea 164: Línea 197:
   (5,-1)   (5,-1)
  
 +Haskell también maneja listas de manera directa, pero lo veremos más adelante.
  
  
Línea 169: Línea 203:
  
 A manera de ejemplo veamos el ejercicio 8.7 del apunte, donde tenemos que definir una función muy útil para cualquier aparato que maneje un calendario (relojes, celulares, PDAs, computadoras, DVD-R, etc.). A manera de ejemplo veamos el ejercicio 8.7 del apunte, donde tenemos que definir una función muy útil para cualquier aparato que maneje un calendario (relojes, celulares, PDAs, computadoras, DVD-R, etc.).
-La signatura ((Signatura es el nombre de la función junto al tipo de sus parámetros y resultado)) es //bisiesto: Int -> Bool//, y es un predicado que devuelve //true// si el año es bisiesto y //false// en caso contrario.+La signatura es //bisiesto: Int -> Bool//, y es un predicado que devuelve //true// si el año es bisiesto y //false// en caso contrario.
 Recordemos cuando un año es [[http://es.wikipedia.org/wiki/Bisiesto|bisiesto]]: Recordemos cuando un año es [[http://es.wikipedia.org/wiki/Bisiesto|bisiesto]]:
  
Línea 221: Línea 255:
 Para realizar en lo que resta de la clase. Para realizar en lo que resta de la clase.
  
-  * Definir la función //sumaRat (a,b) (c,d)//, //sumaRat : (Int,Int) -> (Int,Int) -> (Int,Int)// que suma dos números racionales.\\ No es necesario realizar ninguna simplificación al resultado.+  * Definir la función //sumaRat (a,b) (c,d)//, //sumaRat : (Int,Int) -> (Int,Int) -> (Int,Int)// que suma dos números racionales. En esta función vamos a usar las tuplas para agrupar datos. En este caso, vamos a representar un número racional mediante una tupla, de forma que el numerador sea el primer elemento de la tupla, y el denominador sea el segundo. Por ejemplo, representamos ''3/4'' como ''(3,4)'', representamos ''5/2'' como ''(5,2)'', etc.  
 + 
 + No es necesario realizar ninguna simplificación al resultado.
  
   probar con (1,2) y (1,2), (1,4) y (1,4).   probar con (1,2) y (1,2), (1,4) y (1,4).
introalg/taller08_1.1205875057.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)