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;2004