Haskell Hero
Haskell Hero es un manual interactivo del lenguaje Haskell para principiantes.
|
Listas IIRangos
Hasta ahora hemos definido listas escribiendo elementos individuales. Es decir, cuando necesitabamos una lista de números enteros desde uno hasta cinco, lo escribimos de esta manera:
La lista de números desde uno hasta cinco escribimos como Ejemplos
[1..10] ~>* [1,2,3,4,5,6,7,8,9,10] [10..] = [10,11,12,13,14,15, ... ] take 3 [10..] ~>* [10,11,12] [20..10] ~>* [] ['a'..'f'] ~>* "abcdef"
Después nos gustaría tener una lista de todos números impares desde uno hasta diez. Esta podemos escribir de manera siguiente:
Si Ejemplos
[1,3..10] ~>* [1,3,5,7,9] [10,20..] = [10,20,30,40,50 ... ] [1,2..0] ~>* [] [10,9..1] ~>* [10,9,8,7,6,5,4,3,2,1] [10,9..20] ~>* [] ['f','d'..'a'] ~>* "fdb" ['&','&'..] = "&&&&&&&&&&&& ... " Listas intensionalesEjemploDefinid una lista creciente de todos los números desde uno hasta un millón que son o pares o divisibles por cinco. Ya sabemos de clases de matemática como escribir un conjunto de números que cumplan estas condiciones: { x | x es del conjunto {1,..., 1000000}, x es par o es divisible por 5}En Haskell la notación es muy similar: [ x | x <- [1..1000000], even x || x `mod` 5 == 0]¿Cómo se evaluará tal expresión? Hugs recorre todos los elementos de la lista [1..1000000] y prueba si cumplen la condición
even x || x `mod` 5 == 0Si cumplen la condición, lo añade en la lista final. Si no cumplen, prueba el elemento siguiente.
La construcción ¿Qué pasa cuando hay más generadores en la notación? Pongamos un ejemplo corto: [ (x,y) | x <- [1..3], y <- [1..x] ]¿Cómo se evaluará esta lista?
La lista final será entonces la siguiente: [ (1,1), (2,1), (2,2), (3,1), (3,2), (3,3) ]Si hay tres generadores, la expresión se evalúa de la misma manera. Otros ejemplos
[ 2*x | x <- [1..5] ] ~>* [2,4,6,8,10] map f s = [ f x | x <- s ] filter p s = [ x | x <- s, p x ] |