Herramientas de usuario

Herramientas del sitio


introalg:taller07_2

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:taller07_2 [2007/04/17 15:39] nicolaswintroalg:taller07_2 [2018/08/10 03:03] (actual) – editor externo 127.0.0.1
Línea 159: Línea 159:
   Main> ordenaCabeza (take 10 (repeat (2,1)))   Main> ordenaCabeza (take 10 (repeat (2,1)))
   (1,2)   (1,2)
 +
  
  
Línea 195: Línea 196:
 unidadDeMil n = (n `div` 1000) `mod` 10 unidadDeMil n = (n `div` 1000) `mod` 10
 </code> </code>
 +
 +Siempre es conveniente ser desconfiado y probamos que ambas funciones sean iguales en el rango //[0,9999]//
 +
 +  Main> filter pip [0..9999] == filter pip' [0..9999]
 +  True
  
 Y hasta podemos generalizar las funciones //unidad, decena, etc.// en una que nos dé el dígito n-ésimo de la representación decimal, pero para eso necesitamos usar **funciones recursivas**.\\ Y hasta podemos generalizar las funciones //unidad, decena, etc.// en una que nos dé el dígito n-ésimo de la representación decimal, pero para eso necesitamos usar **funciones recursivas**.\\
Línea 217: Línea 223:
   Main> digitos 123123123   Main> digitos 123123123
   [3,2,1,3,2,1,3,2,1]   [3,2,1,3,2,1,3,2,1]
 +
 +
 +
  
  
Línea 226: Línea 235:
  
 <code> <code>
-descuento :: (Int,Bool) -> (Float,Int,Float) +descuento :: (Float,Bool) -> (Float,Float,Float) 
--- argumento: una tupla (Int,Bool) que representa el monto (Int) y si tenemos tickets (Bool) +-- argumento: un par que representa el monto (Float) y si tenemos tickets (Bool) 
--- resultado: una tresupla (Float,Int,Float) que representa el monto total, +-- resultado: una tresupla (Float,Float,Float) que representa el monto total, 
 --            restando el descuento correspondiente, el número de puntos  --            restando el descuento correspondiente, el número de puntos 
 --            y el descuento en tickets, respectivamente. --            y el descuento en tickets, respectivamente.
  
-descuento x y | x == 257 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +descuento (x,y| x == 257 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x == 257 && y == False = ( x - 0.2*x , 10*x, 0) +                | x == 257 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x == 350 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +                | x == 350 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x == 350 && y == False = ( x - 0.2*x , 10*x, 0) +                | x == 350 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x == 489 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +                | x == 489 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x == 489 && y == False = ( x - 0.2*x , 10*x, 0) +                | x == 489 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x > 1000 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +                | x > 1000 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x > 1000  && y == False = ( x - 0.2*x , 10*x, 0) +                | x > 1000 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x == 768 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +                | x == 768 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x == 768 && y == False = ( x - 0.2*x , 10*x, 0) +                | x == 768 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x == 999 && y == True = ( x - 0.2*x , 10*x, 0.1*x) +                | x == 999 && y     = ( x - 0.2*x , 10*x, 0.1*x) 
-              | x == 573 && y == False = ( x - 0.2*x , 10*x, 0) +                | x == 573 && not y = ( x - 0.2*x , 10*x, 0) 
-              | x > 500 && x <= 1000 && y == True = ( x - 0.15*x , 5*x, 0.05*x) +                | x > 500 && x <= 1000 && y      = ( x - 0.15*x , 5*x, 0.05*x) 
-              | x > 500 && x <= 1000 && y == False = ( x - 0.15*x , 5*x, 0) +                | x > 500 && x <= 1000 && not  = ( x - 0.15*x , 5*x, 0) 
-              | x > 200 && x <= 500 && y == True = ( x - 0.1*x , 2*x, 0.02*x) +                | x > 200 && x <= 500  && y      = ( x - 0.1*x , 2*x, 0.02*x) 
-              | x > 200 && x <= 500 && y == False = ( x - 0.1*x , 2*x, 0) +                | x > 200 && x <= 500  && not  = ( x - 0.1*x , 2*x, 0) 
-              | x <= 200 = ( x , x , 0 )+                | x <= 200 = ( x , x , 0)
 </code> </code>
  
Línea 254: Línea 263:
  
 <code> <code>
-descuento :: (Int,Bool) -> (Float,Int,Float) +descuento:: (Float,Bool) -> (Float,Float,Float) 
-descuento (x,y) | x == 257 || x == 350 || x == 489 || x == 768 || x == 999 || x == 573 = descuento20 (x,y) +descuento(x,y) | x == 257 || x == 350 || x == 489 || x == 768 || x == 999 || x == 573 = descuento20 (x,y) 
-                | x > 1000 = descuento20 (x,y) +                 | x > 1000 = descuento20 (x,y) 
-                | x > 500 && x <= 1000 = descuento15 (x,y) +                 | x > 500 && x <= 1000 = descuento15 (x,y) 
-                | x > 200 && x <= 500 = descuento10 (x,y) +                 | x > 200 && x <= 500 = descuento10 (x,y) 
-                | x <= 200 = descuento0 (x,y)+                 | x <= 200 = descuento0 (x,y)
  
-descuento20 :: (Int,Bool) -> (Float,Int,Float)+descuento20 :: (Float,Bool) -> (Float,Float,Float)
 descuento20 (x,y) | y == True = ( x - 0.2*x , 10*x, 0.1*x) descuento20 (x,y) | y == True = ( x - 0.2*x , 10*x, 0.1*x)
                   | y == False = ( x - 0.2*x , 10*x, 0)                   | y == False = ( x - 0.2*x , 10*x, 0)
  
-descuento15 :: (Int,Bool) -> (Float,Int,Float)+descuento15 :: (Float,Bool) -> (Float,Float,Float)
 descuento15 (x,y) | y == True = ( x - 0.15*x , 5*x, 0.05*x) descuento15 (x,y) | y == True = ( x - 0.15*x , 5*x, 0.05*x)
                   | y == False = ( x - 0.15*x , 5*x, 0)                   | y == False = ( x - 0.15*x , 5*x, 0)
  
-descuento10 :: (Int,Bool) -> (Float,Int,Float)+descuento10 :: (Float,Bool) -> (Float,Float,Float)
 descuento10 (x,y) | y == True = ( x - 0.1*x , 2*x, 0.02*x) descuento10 (x,y) | y == True = ( x - 0.1*x , 2*x, 0.02*x)
                   | y == False = ( x - 0.1*x , 2*x, 0)                   | y == False = ( x - 0.1*x , 2*x, 0)
  
-descuento0 :: (Int,Bool) -> (Float,Int,Float) +descuento0 :: (Float,Bool) -> (Float,Float,Float) 
-descuento0 (x,y) = ( x , x , 0 )+descuento0 (x,y) = ( x , x , 0)
 </code> </code>
  
  
-==== Algo un poco más ordenado ====+ 
  
  
 ===== Estilo de Código (coding style) ===== ===== Estilo de Código (coding style) =====
 +
 +
 +
 +
  
 ==== Reglas de sangrado (layout) (distribución) ==== ==== Reglas de sangrado (layout) (distribución) ====
Línea 293: Línea 307:
   * el código que forma parte de una expresión (o bloque) tiene que indentarse más adentro que la línea que contiene el principio de esa expresión.   * el código que forma parte de una expresión (o bloque) tiene que indentarse más adentro que la línea que contiene el principio de esa expresión.
  
-Por ejemplo, cuando usamos una lista de instrucciones de la misma clase dentro de una función, deben estar todas indentadas a la misma altura, como si estuvierna formando una **columna**, o, si no, más adentro. Vean en el siguiente ejemplo como "//frente//", "//lado//" y "//tapa//" están todas a la misma altura de indentación, formando una columna, y más indentadas que la palabra "//where//", que introduce la expresión dentro de la cual se encuentran:+Por ejemplo, cuando usamos una lista de instrucciones de la misma clase dentro de una función, deben estar todas indentadas a la misma altura, como si estuvieran formando una **columna**, o, si no, más adentro. Vean en el siguiente ejemplo como "//frente//", "//lado//" y "//tapa//" están todas a la misma altura de indentación, formando una columna, y más indentadas que la palabra "//where//", que introduce la expresión dentro de la cual se encuentran:
  
-  area.a.b.c = 2*frente + 2*lado + 2*tapa+  area a b c = 2*frente + 2*lado + 2*tapa
      where      where
         frente = a*b         frente = a*b
Línea 304: Línea 318:
   PREGUNTA: ¿Cómo podemos escribir esta función usando puntuación en lugar de indentación?   PREGUNTA: ¿Cómo podemos escribir esta función usando puntuación en lugar de indentación?
  
-Esto estaría mal si lo escribiéramos de la siguiente forma:+Esto sigue siendo válido si escribimos:
  
-  area.a.b.c = 2*frente + 2*lado + 2*tapa+  area a b c = 2*frente + 2*lado + 2*tapa
      where      where
      frente = a*b      frente = a*b
Línea 312: Línea 326:
      tapa = a*c      tapa = a*c
  
-Y también si lo escribiéramos así:+Pero no cuando las //definiciones locales// están en la misma columna que la definición global de ''area''.
  
-  area.a.b.c = 2*frente + 2*lado + 2*tapa+  area a b c = 2*frente + 2*lado + 2*tapa
      where      where
-    frente = a*b +  frente = a*b 
-    lado = b*c +  lado = b*c 
-    tapa = a*c+  tapa = a*c 
 + 
 +Simplemente no sabe que el ''b'' de la definición de frente es el parámetro ''b'' de ''area''
 + 
 +  Main> :e 
 +  ERROR "1.hs":69 - Undefined variable "b" 
  
 Para ver más ejemplos, vayan al [[http://en.wikibooks.org/wiki/Haskell/Indentation|apartado sobre indentación]] del [[http://en.wikibooks.org/wiki/Haskell/|wikibook de Haskell]]. Para ver más ejemplos, vayan al [[http://en.wikibooks.org/wiki/Haskell/Indentation|apartado sobre indentación]] del [[http://en.wikibooks.org/wiki/Haskell/|wikibook de Haskell]].
Línea 324: Línea 344:
 Para saber más, vean la [[http://haskell.org/onlinereport/lexemes.html#lexemes-layout|descripción informal]] o [[http://haskell.org/onlinereport/syntax-iso.html#layout|más formal]] de este tema en el [[http://haskell.org/onlinereport/|Haskell Report]]. Para saber más, vean la [[http://haskell.org/onlinereport/lexemes.html#lexemes-layout|descripción informal]] o [[http://haskell.org/onlinereport/syntax-iso.html#layout|más formal]] de este tema en el [[http://haskell.org/onlinereport/|Haskell Report]].
  
-Y ya que estamos, sepan que toda línea que comienza por dos guiones (o signos "menos") no será interpretada por el intérprete de Haskell, de esta forma se pueden introducir comentarios en los programas.+Y ya que estamos, sepan que toda **línea** que comienza por dos guiones (o signos "menos") no será interpretada por el intérprete de Haskell, de esta forma se pueden introducir comentarios en los programas. 
 +Y para evitar que se interpreten **bloques completos**, a éstos los demarcamos con ''{- bloque -}'' 
 + 
 +<code> 
 +-- Nada de esto se toma 
 +{- Y esto 
 +   tampoco! 
 +-} 
 +</code> 
  
 ==== Case sensitiveness (sensibilidad a la caja) ==== ==== Case sensitiveness (sensibilidad a la caja) ====
Línea 335: Línea 364:
  
   * los nombres de **funciones y variables** comienzan con **minúscula**   * los nombres de **funciones y variables** comienzan con **minúscula**
 +
 +
 +
 +
 +==== Nombres de variables ====
 +
 +En general se intenta que el código sea auto explicativo, en el sentido que baste con leerlo para comprender como funciona.
 +Algo que resulta muy sencillo y útil es dar nombres significativos a las variables.
 +Podríamos haber escrito la función área de la siguiente manera.
 +
 +  area a1 a2 a3 = 2*a4 + 2*a5 + 2*a6
 +     where
 +        a4 = a1*a2
 +        a5 = a2*a3
 +        a6 = a1*a3
 +
 +o bien de manera equivalente e igualmente eficiente, pero mucho más comprensible:
 +
 +  area b a p = 2*frente + 2*lado + 2*tapa
 +     where
 +        frente = b * a
 +        lado = p * a
 +        tapa = b * p
 +
  
 ===== Ejercicios ===== ===== Ejercicios =====
Línea 347: Línea 400:
   probar con [1,2,3], con [3,3,3] y con [].   probar con [1,2,3], con [3,3,3] y con [].
  
-  * Definir una función //esVaciaOPrimer0.xs//, //esVaciaOPrimer0 : [a] -> Bool// que dada una lista //xs// decida si //xs// es vacía o bien su primer elemento es 0.+  * Definir una función //esVaciaOPrimer0.xs//, //esVaciaOPrimer0 : [Int] -> Bool// que dada una lista //xs// decida si //xs// es vacía o bien su primer elemento es 0.
  
   probar con [1,2,3], con [3,3,3], con [0], con [0,1] y con [].   probar con [1,2,3], con [3,3,3], con [0], con [0,1] y con [].
  
-  * Definir una función //segundoEssegundo.(x,y).zs//, //segundoEssegundo : (Int,Int) -> [Int] -> Bool// que dada una tupla de enteros //(x,y)// y una lista de enteros //zs// comprueba si el segundo elemento de la tupla es igual al segundo elemento de la lista.+  * Definir una función //segundoEsSegundo.(x,y).zs//, //segundoEsSegundo : (Int,Int) -> [Int] -> Bool// que dada una tupla de enteros //(x,y)// y una lista de enteros //zs// comprueba si el segundo elemento de la tupla es igual al segundo elemento de la lista.
  
   probar con (1,2) y [3,2,4,5], (0,0) y [], (1,2) y [2,3,4,5].   probar con (1,2) y [3,2,4,5], (0,0) y [], (1,2) y [2,3,4,5].
  
-  * Definir una función //recortaDia.xs//, //recortaDia : [Char] -> [Char]// que dada una lista de caracteres //xs//, comprueba si las letras de la lista forman el nombre de un día de la semana, si es así, si el día es de diario, devuelven la primera letra solamente, en cambio, si el día es de fin de semana, devuelven el nombre del día completo.+  * Definir una función //recortaDia.xs//, //recortaDia : [Char] -> [Char]// que dada una lista de caracteres //xs//, comprueba si las letras de la lista forman el nombre de un día de la semana, si es así, si el día no es del fin de semana, devuelven la primera letra solamente, en cambio, si el día es de fin de semana, devuelven el nombre del día completo.
 Ayuda: fíjense que el resultado siempre debe ser una lista de caracteres! Ayuda: fíjense que el resultado siempre debe ser una lista de caracteres!
  
introalg/taller07_2.1176824354.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)