2011-04-13 6 views
11

sólo he estado en Haskell desde hace dos días, y se preguntaba cuál es la diferencia entre las dos definiciones de las funciones siguientes son:Sintaxis para la construcción de la lista/concatenación

Prelude> let swap (x1:x2:xs) = x2:x1:xs 
Prelude> swap [1..5] 
[2,1,3,4,5] 
Prelude> let swap' (x1:x2:xs) = [x2] ++ [x1] ++ xs 
Prelude> swap' [1..5] 
[2,1,3,4,5] 

Es decir, lo que hace que x2: x1 : xs diferente de [x2] ++ [x1] ++ xs? Por favor y gracias.

+2

¿Qué quiere decir diferente? Sus denotaciones son las mismas, es decir, swap y swap 'hacen lo mismo. – augustss

Respuesta

25

Las firmas de tipos son un buen punto de partida:

(:) :: a -> [a] -> [a] 
(++) :: [a] -> [a] -> [a] 

Usted puede encontrar estos con :type (:) y :type (++) en ghci.

Como se puede ver en las firmas de tipos, ambos se utilizan para producir las listas.

El operador : se utiliza para construir las listas (y para llevarlos aparte de nuevo por la coincidencia de patrones). Para hacer una lista [1,2,3] que acaba de construir con 1 : 2 : 3 : []. El primer elemento de : es el elemento que desee agregar en el frente de la lista, y el segundo elemento es o bien una lista (también construido con : o la lista vacía significado por []).

El operador es ++ lista de concatenación. Toma dos listas y las agrega juntas. [1,2,3] ++ [4,5,6] es legal, mientras que 1 ++ [1,2,3] no lo es.

+0

Se está volviendo más claro. Con el superior, estaba creando una lista de una lista, mientras que con la de abajo creé 3 y los recuperé todos juntos. ¿Eso significa que el superior sería más rápido/más eficiente? –

+0

En la parte superior, está creando la lista por los dos primeros elementos intercambiados y la misma cola. En el segundo, está creando la lista separando los dos primeros, luego compilándolos en listas y concatecándolos con la cola. Supongo que el primero sería más eficiente, pero no creo que eso sea lo más importante. El primero es Haskell más idiomático en mi opinión, así que es por eso que debes elegirlo. –

+0

Gracias! Después de las explicaciones aquí y más de estudiar hoy, todo tiene más sentido. –

3

Esto no tiene nada que ver con la sintaxis. (:) y (++) son solo operadores diferentes. (:) es un constructor que construye una lista de un elemento y otra lista. (++) crea una nueva lista que es la concatenación de dos listas. Como (++) no es un constructor, no puedes usarlo en patrones.

Ahora llegamos a Sintaxis: la notación

[x2] 

que se utiliza es una abreviatura de

x2:[] 

Así que lo que realmente ha hecho en el segundo ejemplo es:

(x2:[]) ++ (x1:[]) ++ xs 

Por lo tanto, al construir una lista, no se puede evitar (:), es la única forma de hacerlo. Tenga en cuenta que debe construir listas intermedias para poder usar (++).

Cuestiones relacionadas