Haskell: Sintaxis Basica II
Mayo 18 2009 :: Haskell, Programación Funcional ::
Algunos detalles más de Sintaxis de Funciones: Uso de Where, de Let y definición de listas por comprensión.
Ej: una función que tomando una cantidad de segundos devuelve las horas, minutos y segundos que representa (Ejercicio 2.26 de Razonando con Haskell)-
aHoras:: Integer -> ( Integer, Integer, Integer )
aHoras x = ( horas, minutos, segundos )
where
m = div x 60
h = div m 60
segundos = mod x 60
minutos = mod m 60
horas = mod h 60
Otro Ej: un listado (no muy eficiente) de los números perfectos. (Ejercicio 6.19)
divideA :: Integer -> Integer -> Bool
divideA x y = mod x y == 0
divisoresDe :: Integer -> [Integer]
divisoresDe n = [x | x <- [1..(n-1)], divideA n x]
perfecto :: Integer -> Bool
perfecto x = suma == x
where
ds = divisoresDe x
suma = sum ds
perfectos :: [Integer]
perfectos = [x | x <- [0..], perfecto x ]
Otra posible definición usando let.
perfectos2 :: [Integer]
perfectos2 = [x | x <- [0..], let ds = divisoresDe x, let suma = sum ds, x == suma]
Listas por extensión, Las ternas pitagóricas (Ejemplo 6.20):
ternasPit :: Integer -> [(Integer, Integer, Integer)]
ternasPit n = [(x,y,z) | let ns = [1..n], x <- ns, y <- ns, z <- ns, x^2 + y^2 == z^2 ]
Una definición de Quicksort (Ejemplo 6.10.3)
quickSort :: Ord a => [a] -> [a]
quickSort [] = []
quickSort (p:xs) = quickSort menores ++ [p] ++ quickSort mayores
where
menores = [x | x <- xs, x < p ]
mayores = [x | x <- xs, x >= p ]
Otra definición de Quicksort más eficiente (Ejercicio 6.30)
partirPor :: Ord a => (a -> Bool) -> [a] -> ([a], [a])
partirPor f [] = ([], [])
partirPor f [x] | f x = ([x], [])
| otherwise = ([], [x])
partirPor f (x:xs) | f x = (x:ys, zs)
| otherwise = (ys, x:zs)
where
(ys, zs) = partirPor f xs
{-
*Main> partirPor even [1..10]
([2,4,6,8,10],[1,3,5,7,9])
-}
quickSort2 :: Ord a => [a] -> [a]
quickSort2 [] = []
quickSort2 (p:xs) = quickSort2 menores ++ [p] ++ quickSort2 mayores
where
(menores, mayores)= partirPor (\x -> x < p) xs
Trabajando con Funciones como argumentos.
Una función que recibe una lista de funciones y un entero, devuelve la lista de resultados. (Ejercicio 2.28)
(|>)::[Integer -> Integer] -> Integer -> [Integer]
(|>) [] x = []
(|>) (f:fs) x = f x : (|>) fs x
Se puede probar con expresiones lambda:
Main> (|>) [(\x -> x * 10), (\x -> x +10), (\x -> x*20)] 5
[50,15,100]
Una función que devuelve el primer elemento de una lista que cumple con una determinada condición. (Ejercicio 6.18)
primeroQue :: (a -> Bool) -> [a] -> a
primeroQue f (x:xs) | f x == True = x
| otherwise = primeroQue f xs
Seudónimos
La función:
factorial :: Integer -> Integer
factorial 0 = 1
factorial (n + 1) = (n + 1) * factorial n
puede escribirse como:
factorial :: Integer -> Integer
factorial 0 = 1
factorial m@(n + 1) = m * factorial n
donde m = ( n + 1).
Referencias
Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004Autor: Emiliano Martínez Luque.


Deja un Comentario
Guía de los comentarios
Tu Email es requerido pero no sera publicado.
Podes usar los siguientes tags de HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>Si no comentastes antes tu comentario debera ser aprovado antes de que se lo muestre. Perdón, pero hay demasiado spam.