Tutorial Haskell #5: Funciones de Lista I

Importante: muchos de los ejemplos a continuación no finalizan nunca (intentan mostrar una lista infinita o su último elemento). Para regresar al intérprete hace falta interrumpir la ejecución presionando ^C (las teclas Ctrl y c al mismo tiempo).

Las siguientes operaciones están definidas en la biblioteca estándar de Haskell para trabajar con listas:

(++) concatena dos listas:

Prelude> [1..10]
[1,2,3,4,5,6,7,8,9,10]
Prelude> [100..110]
[100,101,102,103,104,105,106,107,108,109,110]
Prelude> [1..10] ++ [100..110]
[1,2,3,4,5,6,7,8,9,10,100,101,102,103,104,105,106,107,108,109,110]

concat concatena varias listas que estén a su vez dentro de una lista. Recordar que una cadena de texto (e.g. "foo ") es en realidad una lista de caracteres (i.e. ['f', 'o', 'o', ' '] ó 'f':'o':'o':' ':[])

Prelude> concat ["foo ", "bar ", "baz "]
"foo bar baz "
Prelude> concat [[1..3], [4,7..15], [99,1024..3000]]
[1,2,3,4,7,10,13,99,1024,1949,2874]

head regresa el primer elemento de una lista. Se puede emplear en listas infinitas, dado que nunca se tiene que inspeccionar ningún elemento más adelante.

Prelude> head "hola"
'h'
Prelude> head [10..20]
10
Prelude> head [10..]
10

tail es el complemento de head; regresa una lista igual a su argumento, sin el primer elemento. Si el argumento es lista infinita, su 'tail' es también lista infinita. La lista vacía no tiene ni 'head' ni 'tail'.

Prelude> tail "hola"
"ola"
Prelude> tail [1..10]
[2,3,4,5,6,7,8,9,10]
Prelude> tail []
*** Exception: Prelude.tail: empty list
Prelude> head []
*** Exception: Prelude.head: empty list

init y last son duales a head y tail. last regresa el último elemento de una lista no infinita, e init regresa una lista de todos los elementos menos el último. 'init' de una lista infinita es la misma lista. 'last' de una lista infinita nunca finaliza.

Prelude> init "hola"
"hol"
Prelude> last "hola"
'a'
Prelude> init [1..10]
[1,2,3,4,5,6,7,8,9]
Prelude> last [1..10]
10
Prelude> init [1..]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14^CInterrupted.
Prelude> last [1..]
^CInterrupted.

take construye una lista a partir de los primeros n elementos de una lista, posiblemente infinita. drop es su complemento, que devuelve la lista sin los primeros n elementos. splitAt hace las dos cosas al mismo tiempo y devuelve ambos resultados en un par.

Prelude> take 3 "Hola mundo"
"Hol"
Prelude> drop 3 "Hola mundo"
"a mundo"
Prelude> splitAt 3 "Hola mundo"
("Hol","a mundo")

length regresa la longitud de una lista no infinita. En caso de lista infinita no finaliza nunca.

Prelude> length "hola"
4
Prelude> length [1..10]
10
Prelude> [7,16..99]
[7,16,25,34,43,52,61,70,79,88,97]
Prelude> length [7,16..99]
11
Prelude> length [1..]
^CInterrupted.

(!!) regresa el elemento con un índice dado dentro de la lista. Los índices empiezan en cero. Si el índice es demasiado grande se produce una excepción.

Prelude> [1..10] !! 0
1
Prelude> [1..10] !! 10
*** Exception: Prelude.(!!): index too large
 
Prelude> [1..10] !! 9
10

repeat, replicate y cycle construyen listas a partir de elementos. repeat construye una lista infinita que repite indefinidamente al argumento. replicate es similar a repeat, pero toma un argumento indicando el número de repeticiones, y construye una lista no infinita. cycle toma como argumento una lista y produce una lista infinita que cicla los elementos del argumento.

Prelude> repeat 5
[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5Interrupted.
Prelude> replicate 21 5
[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5]
Prelude> length it
21
Prelude> cycle [1,2,3]
[1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2^CInterrupted.
Prelude> cycle "hola "
"hola hola hola hola hola hola hola hola hola hola hola ho^CInterrupted.

lines, words, unlines y unwords son funciones que operan en cadenas, y sirven para separar o unir líneas de texto (delimitadas por '\n') y palabras (delimitadas por espacios).

Al separar una cadena se obtiene una lista de cadenas, y es posible unir una lista de cadenas para obtener una cadena; unwords y unlines son muy parecidas, pero no exactamente iguales a 'concat'.

Prelude> lines "foo bar\nbaz quux"
["foo bar","baz quux"]
Prelude> words "foo bar baz quux"
["foo","bar","baz","quux"]
Prelude> unlines ["foo bar", "baz quux"]
"foo bar\nbaz quux\n"
Prelude> unwords ["foo", "bar", "baz", "quux"]
"foo bar baz quux"

reverse revierte el orden de una lista. Revertir el orden de una lista infinita no finaliza nunca.

Prelude> reverse [1..10]
[10,9,8,7,6,5,4,3,2,1]
Prelude> reverse "hola mundo"
"odnum aloh"
Prelude> reverse [1..]
^CInterrupted.

elem y notElem son funciones booleanas que dicen si un elemento dado se encuentra en la lista. En caso de lista infinita, si el elemento no está en la lista, la ejecución no finaliza, pero en general no se puede estar seguro de que no está si no finaliza ("no computabilidad").

Prelude> elem 5 [1..10]
True
Prelude> notElem 5 [1..10]
False
Prelude> elem 15 [1..10]
False
Prelude> notElem 15 [1..10]
True
Prelude> elem 'o' "Hola"
True
Prelude> notElem 'o' "Hola"
False
Prelude> elem (-1) [1..]
^CInterrupted.

zip y zip3 sirven para unir dos o tres listas en pares o triples de elementos, respectivamente. Si todas las listas son infinitas esto produce una lista infinita. Si al menos una no lo es, entonces la lista resultante tiene la longitud de la lista más corta.

Prelude> zip [1..10] ['a'..'z']
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j')]
Prelude> zip3 [1,3..10] ['a'..'z'] ['c','f'..]
[(1,'a','c'),(3,'b','f'),(5,'c','i'),(7,'d','l'),(9,'e','o')]

Sus (casi) inversas unzip y unzip3 convierten las listas de pares o triples en un par o triple de listas, respectivamente.

Prelude> unzip [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j')]
([1,2,3,4,5,6,7,8,9,10],"abcdefghij")
Prelude> unzip3 [(1,'a','c'),(3,'b','f'),(5,'c','i'),(7,'d','l'),(9,'e','o')]
([1,3,5,7,9],"abcde","cfilo")

Powered by Drupal, an open source content management system