Alberto Pardo Marcos Viera Instituto de Computación, Facultad de Ingeniería Universidad de la República, Uruguay
Operaciones sobre listas
Listas El tipo de las listas es uno de los más usados en PF Su relevancia en PF se compara a la de los conjuntos en la matemática La expresión [m.. n] denota la lista de valores entre m y n. Si m > n denota la lista vacía [ ]. Por ejemplo, [1.. 4] denota la lista [1, 2, 3, 4].
Divisores de un número Ser divisor: m divide n = n mod m == 0
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo):
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo): divisores n = [d d [1.. n], d divide n]
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo): divisores n = [d d [1.. n], d divide n] equivale a divisores n = filter ( divide n) [1.. n]
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo): divisores n = [d d [1.. n], d divide n] equivale a divisores n = filter ( divide n) [1.. n] Máximo común divisor:
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo): divisores n = [d d [1.. n], d divide n] equivale a divisores n = filter ( divide n) [1.. n] Máximo común divisor: mcd x y = maximum [d d divisores x, d divide y ]
Divisores de un número Ser divisor: m divide n = n mod m == 0 Divisores de un entero positivo (incluyéndolo): divisores n = [d d [1.. n], d divide n] equivale a divisores n = filter ( divide n) [1.. n] Máximo común divisor: mcd x y = maximum [d d divisores x, d divide y ] equivale a mcd x y = maximum filter ( divide y) divisores $ x donde f $ x = f x
Números primos Determinar si un número es primo:
Números primos Determinar si un número es primo: primo n = divisores n == [1, n]
Números primos Determinar si un número es primo: primo n = divisores n == [1, n] Esto se puede hacer de forma mas eficiente:
Números primos Determinar si un número es primo: primo n = divisores n == [1, n] Esto se puede hacer de forma mas eficiente: primo n = (n > 1) && ([d d [2.. intsqrt n], d divide n] == [ ]) intsqrt n es el mayor entero cuyo cuadrado es menor o igual a n, o sea, n
Números perfectos Factores de un número (divisores menores que el número): factores n = filter ( divide n) [1.. n div 2]
Números perfectos Factores de un número (divisores menores que el número): factores n = filter ( divide n) [1.. n div 2] Se dice que un número es perfecto si la suma de sus factores es igual al número: perfecto n = sum (factores n) == n
Números perfectos Factores de un número (divisores menores que el número): factores n = filter ( divide n) [1.. n div 2] Se dice que un número es perfecto si la suma de sus factores es igual al número: perfecto n = sum (factores n) == n Números perfectos entre 1 y 100: >filter perfecto [1.. 100]
Números perfectos Factores de un número (divisores menores que el número): factores n = filter ( divide n) [1.. n div 2] Se dice que un número es perfecto si la suma de sus factores es igual al número: perfecto n = sum (factores n) == n Números perfectos entre 1 y 100: >filter perfecto [1.. 100] [6, 28]
take y drop Dado un entero no negativo n y una lista xs: take n xs retorna el segmento inicial de xs de largo n si su largo es menor que n retorna toda xs drop n xs retorna la lista luego de sacar los primeros n elementos de xs si su largo es menor que n retorna la lista vacía take y drop satisfacen que: take n xs + drop n xs == xs
Ejemplos Retornar una lista menos su último elemento. init :: [a] [a] init xs = take (length xs 1) xs
Ejemplos Retornar una lista menos su último elemento. init :: [a] [a] init xs = take (length xs 1) xs Último elemento de una lista. last :: [a] a last xs = head $ drop (length xs 1) xs
Ejemplos Retornar una lista menos su último elemento. init :: [a] [a] init xs = take (length xs 1) xs Último elemento de una lista. last :: [a] a last xs = head $ drop (length xs 1) xs Partir una lista en dos en un determinado lugar. splitat :: Int [a] ([a], [a]) splitat n xs = (take n xs, drop n xs)
trail La función trail es un ejemplo de diseño composicional. La llamada trail n retorna las últimas n ĺıneas de un texto. trail :: Int String String trail n = unlines reverse take n reverse lines La función lines separa un texto en ĺıneas; unlines es su inversa. lines :: String [String ] unlines :: [String ] String
La función zip zip :: [a] [b] [(a, b)
La función zip zip :: [a] [b] [(a, b) Producto escalar de dos vectores (dados como listas):
La función zip zip :: [a] [b] [(a, b) Producto escalar de dos vectores (dados como listas): prodesc :: Num a [a] [a] a prodesc xs ys = sum map (uncurry ( )) $ zip xs ys
La función zip zip :: [a] [b] [(a, b) Producto escalar de dos vectores (dados como listas): prodesc :: Num a [a] [a] a prodesc xs ys = sum map (uncurry ( )) $ zip xs ys Determinar si una secuencia es no decreciente:
La función zip zip :: [a] [b] [(a, b) Producto escalar de dos vectores (dados como listas): prodesc :: Num a [a] [a] a prodesc xs ys = sum map (uncurry ( )) $ zip xs ys Determinar si una secuencia es no decreciente: nondec :: Ord a [a] Bool nondec xs = and map (uncurry ( )) $ zip xs (tail xs) donde and bs es True si todos los elementos de la lista (de booleanos) bs son True.
La función zipwith zipwith :: (a b c) [a] [b] [c ] zipwith f = map (uncurry f ) (zip xs ys)
La función zipwith zipwith :: (a b c) [a] [b] [c ] zipwith f = map (uncurry f ) (zip xs ys) Usando zipwith podemos definir prodesc y nondec: prodesc xs ys = sum $ zipwith ( ) xs ys nondec xs = and $ zipwith ( ) xs (tail xs)
La función foldr foldr :: (a b b) b [a] b Dada un operador y un valor e, la función foldr ( ) e cuando es aplicada a una lista [x 1,..., x n ], es decir, x 1 : x 2 : x 3 :... : x n : [ ], o que es lo mismo, x 1 : (x 2 : (x 3 :... : (x n : [ ])...)) retorna el valor x 1 (x 2 (x 3...(x n e)...)) En otras palabras, foldr sustituye (:) por ( ) y [ ] por e.
Ejemplos sum :: Num a [a] a sum = foldr (+) 0 and :: [Bool ] Bool and = foldr (&&) True map :: (a b) [a] [b] map f = foldr (cons f ) [ ] where cons x xs = x : xs filter :: (a Bool) [a] [a] filter p = foldr op [ ] where op a r p a = a : r otherwise = r