2011-12-12 72 views
10

Estoy tratando de escribir una función haskell que toma dos listas de enteros y genera una lista con elementos que han sido tomados alternativamente de las dos listas.Haskell - elementos alternados de dos listas

I tienen la función:

blend xs ys 

Un ejemplo:

blend [1,2,3] [4,5,6] 

debe devolver

[1,4,2,5,3,6] 

Mi lógica es para comprimir las dos listas, generando los pares de alterna elementos, luego de alguna manera eliminarlos de sus tuplas.

Es eliminarlos de sus tuplas que no puedo encontrar cómo implementarlos.

Respuesta

18

¿Qué hay de intercambiar los argumentos durante la recursión descendente?

blend (x:xs) ys = x:(blend ys xs) 
blend _ _ = [] 

Incluso se puede generalizar este enfoque para cualquier número de listas (Voy a dejar esto a usted) o llevar a los restantes elementos de una lista si el otro está vacío:

blend _ ys = ys 
+0

¡Manera muy buena de hacerlo! Gracias. – Shabu

6

lo haré asumir que esto es tarea. Siempre que pueda crear la lista siguiente (como usted ha dicho):

[(1,4),(2,5),(3,6)] 

... se puede resolver con 2 funciones:

  1. es necesario convertir una tupla (a, b) en una lista [a, b]. ¡Prueba a usar la coincidencia de patrones! Esta función debe aplicarse (también conocida como mapeada) sobre todos los elementos de la lista que tenga.
  2. Tendrá una lista de listas, como [[1,4],[2,5],[3,6]], por lo que necesita una función para concatenar las sublistas en una lista grande.

Existen, por supuesto, otras formas, quizás superiores, de resolver este problema, pero podría ser una buena idea continuar con su enfoque original.

+1

Creo que una respuesta a una pregunta '[tarea]' que continúa en la dirección original es particularmente útil (a menos que la dirección fuera completamente incorrecta, que, en este caso, no lo era). –

4

Si desea comprimir, generar listas en lugar de tuplas:

concat $ zipWith (\x y -> [x,y]) [1,2,3] [4,5,6] 

Un poco de diversión sin sentido:

concat $ zipWith ((flip(:)).(:[])) [1,2,3] [4,5,6] 

Probablemente la forma más fácil:

import Data.List 
concat $ transpose [[1,2,3],[4,5,6]] 
2

Una solución sin utilizar concat o recursión explícita:

blend l = foldr($)[] . zipWith(.) (map(:)l) . map(:) 

Podemos hacer también hacer este punto libre

blend' = (foldr($)[].) . (.map(:)) . zipWith(.) . map(:) 


Cómo funciona: primero decorar las dos listas con los operadores cons

\[1,2,3] [4,5,6] -> [1:, 2:, 3:] [4:, 5:, 6:] 

entonces zip esto junto con la composición de funciones

-> [(1:).(4:), (2:).(5:), (3:).(6:)] 

y finalmente doblar la aplicación de todas estas composiciones de la derecha a la lista vacía

-> (1:).(4:) $ (2:).(5:) $ (3:).(6:) $ [] = 1:4:2:5:3:6:[] = [1,4,2,5,3,6] 
+0

¿Qué pasa con esto? – leftaroundabout

Cuestiones relacionadas