Haskell Hero

Haskell Hero es un manual interactivo del lenguaje Haskell para principiantes.

Funciones útiles I

id

La función unaria que devuelve el parámetro sin cambios.

Definición

id  :: a -> a
id x = x

Ejemplo de uso

id 5 ~> 5
id "hola" ~> "hola"
(id even) 3 ~> even 3 ~> False

Un ejemplo más complejo

comp     ::  Int -> (a -> a) -> a -> a
comp 0 _  =  id
comp n f  =  f . comp (n-1) f
La expresión comp n f x se evalúa de esta manera: Al elemento x se aplica n-veces la función f. La función id funciona aquí como un caso base cuando el valor del primer parámetro llega a ser cero.
comp 5 (+2) 10

~>*  ( (+2) . (+2) . (+2) . (+2) . (+2) . id ) 10
El operador (.) se describe en el último párrafo.

const

La función binaria que devuelve su primer parámetro sin cambios.

Definición

const    :: a -> b -> a
const x y = x

Ejemplos de uso

const 5 'q' ~> 5
const True (+8) ~> True
(const div "ffuu") 10 3 ~> div 10 3 ~> 3

Más información

La expresión (const div "ffuu") 10 3 se evalúa de manera siguiente:

  • Hugs empieza a evaluar de la izquierda. Esto significa que mira primero la función const.
  • Identifica que la función const es binaria, es decir, necesita para dos parámetros para su evaluación completa.
  • Las primeras dos cosas que encuentra son la función div y la cadena "ffuu".
  • Estos dos parámetros son suficientes para la evaluación, entonces la función const se evalúa según la definición de su primer parámetro, lo que es div.
  • La función div se aplica a los números 10 y 3.

flip

La función ternaria que toma como parámetros:

  • Una función binaria f de tipo a -> b -> c
  • Cualquier cosa se puede usar como el segundo parámetro de la función f, de tipob
  • Cualquier cosa se puede usar como el primer parámetro de la función f, de tipo a

La función flip cambia el orden del segundo y del tercer parámetro y estos parámetros pasan para la evaluación a la función f, el resultado de tipo c.

Definición

flip       ::  (a -> b -> c) -> b -> a -> c
flip f x y  =  f y x

Ejemplo de uso

flip (-) 3 5  ~>  5 - 3  ~>  2
flip const True "sí"  ~>  const "sí" True  ~>  "sí"

Operadores para la construcción de tuplas

  • Duplas se construyen con el operador binario (,).
  • Triplas se construyen con el operador ternario (,,).
  • Cuádruplas se construyen con el operador (,,,) de aridad 4.
  • ...

Ejemplo de uso

(,)  5     True        ~>  (5, True)
(,,) "aAa" 5.0  False  ~>  ("aAa", 5.0, False)

fst

La función que devuelve el primer elemento de una dupla.

Definición

fst      :: (a,b) -> a
fst (x,_) = x

Ejemplo de uso

fst ("#&!",10.5) ~> "#&!"

snd

La función que devuelve el segundo elemento de una dupla.

Definición

snd       ::  (a,b) -> b
snd (_,y)  =  y

Ejemplo de uso

snd ("#&!",10.5)  ~>  10.5

Composición de funciones


Composición de funciones en el modelo de cajas

Para la composición de funciones usamos el operador ternario (.). La función compuesta (f.g) en la expresión (f.g) x primero aplica al parámetro x la función g y después la función f.

Los parámetros del operador (.) son:

  • la segunda función que se debe aplicar al parámetro, de tipo (b -> c)
  • la primera función que se debe aplicar al parámetro, de tipo (a -> b)
  • el parámetro al que se aplica la función compuesta, de tipo a

El resultado del cálculo es el parámetro tras las aplicaciones de funciones g y f en este orden. El resultado es de tipo c

Definición

(.)       ::  (b -> c) -> (a -> b) -> a -> c
(f . g) x  =  f (g x)

Ejemplo

Definid la función binaria sndOdd que toma el segundo elemento de la dupla de cualquier cosa y un número entero y decide si su valor es impar. Un ejemplo de la evaluación requerida:

sndOdd ("hola",5)  ~>*  True
sndOdd (True,8)    ~>*  False


La función toma una dupla de cualquier cosa y un número entero y devuelve Bool. El tipo de función será el siguiente:

sndOdd  ::  (a,Integer) -> Bool
Una de las opciones es usar la definición con patrones:
sndOdd (_,y)  =  odd y
Nosotros vamos a ver cómo podemos definir esta función con la composición de funciones. Queremos crear una función representada por la caja azul de la imagen arriba. Ponemos una dupla en la caja y Bool se cae de la caja.

Primero extraemos el segundo elemento de la dupla con la función snd:

snd (x,y)
Después aplicamos la función odd al resultado:
odd (snd (x,y))
Este podemos escribir con el operador (.) como una función compuesta. La definición final será la siguiente:
sndOdd (x,y)  =  (odd.snd) (x,y)
Si podemos poner el parámetro de la función completamente a la derecha, podremos omitirlo en la definición. Esta notación la llamaremos pointfree (libre de puntos). La conversión de la función al estilo pointfree la vamos a describir más tarde. Ahora es suficiente saber que la notación siguiente es sustituible por la anterior.
sndOdd  =  odd.snd


La evaluación de la expresión (odd.snd) (True,8)