2012-02-28 9 views
7

Soy nuevo en Haskell (y en la programación funcional en general) y me preguntaba cómo puedo acceder a un elemento nuevo que he agregado a una lista usando el operador contra (:)?¿Cómo accedo a un elemento de lista que he agregado con el operador cons (:)?

Por ejemplo, el uso de WinGHCi puedo crear una nueva lista y acceder al primer elemento:

ghci> let a = [1,2,3] 
ghci> a!!0 
1 

Los vuelve a aparecer 1, el valor del primer elemento, fresco. Ahora añado un nuevo valor a la parte delantera de la lista y tratar de acceder a ella:

ghci> 5:a 
[5,1,2,3] 
ghci> a!!0 
1 

Parece que los elementos de la lista no ser re-indexado. Intenté obtener un índice negativo para el trabajo y otras cosas similares, pero el compilador no pareció aprobar. Los tutoriales que estoy leyendo solo se saltan y no pude encontrar nada de uso en línea. ¿Cómo obtengo el valor "5" de la lista?

Gracias por la ayuda y lo siento si esta es una pregunta muy básica.

+3

Para ilustrar el punto de Marcin, escriba 'a' en GHCI y verá [1,2,3], porque no puede modificar una variable en Haskell. Para aclarar las cosas, considere [estas definiciones de variable y asignable] (http: //existentialtype.wordpress.com/2012/02/01/words-matter /): Haskell tiene 'variables' en el sentido matemático, pero no 'asignables' como en los lenguajes imperativos. –

+0

a sigue siendo [1,2,3] después de 5: a.Thera no tiene efectos secundarios como la mutación en la programación funcional – nist

+0

Ya lo entiendo, es solo otra forma de pensar ... jaja. ¡Gracias a todos! – Awesominator

Respuesta

12

Esta idea se encuentra en el núcleo de programación funcional: usted (por lo general) no está modificando los datos en su lugar. Por lo tanto, no agrega un elemento a una lista: crea una lista nueva sin modificar la anterior.

Esto permite muchas cosas agradables, compartir, por ejemplo, porque nunca cambia los datos antiguos y así puede seguir haciéndolo. Pero también impone una carga si estás acostumbrado a otros paradigmas de programación: tienes que cambiar tu forma de abordar las cosas (y a menudo tienes que cambiar tus estructuras de datos/algoritmos porque estaban confiando en la modificación en el lugar de una estructura de datos) .

En su ejemplo, acaba de dar un nuevo nombre a la lista cons'ed:

let a = [1, 2, 3] 
let b = 5:a 
7

Su malentendido es fundamental: los contras no modifican destructivamente nada.

5:a (donde a = [1,2,3]) evalúa a [5,1,2,3], y eso es lo que el intérprete le está mostrando.

2

Las listas son inmutables:

Prelude> let xs = [1,2,3] 
Prelude> 4:xs 
[4,1,2,3] 
Prelude> xs 
[1,2,3] 
Prelude> let ys = 4:xs 
Prelude> ys 
[4,1,2,3] 

Si quieres cambiar los elementos de la estructura de datos utilizar Arrays.

6

Vamos a ilustrar con (+), así como (:)

Prelude> 4+5 
9 
Prelude> let z = 5 
Prelude> z 
5 
Prelude> 4+z 
9 
Prelude> z 
5 
Prelude> let y = 4+z 
Prelude> y 
9 
Prelude> z 
5 

frente

Prelude> let a = [1,2,3] 
Prelude> a 
[1,2,3] 
Prelude> 5:a 
[5,1,2,3] 
Prelude> a 
[1,2,3] 
Prelude> let b = 5:a 
Prelude> b 
[5,1,2,3] 
Prelude> a 
[1,2,3] 

Las fijaciones hechas con 'let' nunca cambian, pero se pueden hacer otras nuevas. Si un enlace nuevo tiene el mismo nombre que un enlace antiguo, el enlace anterior se "sombreará" y no se mutará.

Cuestiones relacionadas