web-dev-qa-db-fra.com

Fusion de deux listes dans Haskell

Impossible de comprendre comment fusionner deux listes de la manière suivante dans Haskell:

INPUT:  [1,2,3,4,5] [11,12,13,14]

OUTPUT: [1,11,2,12,3,13,4,14,5]
24
bogatyrjov
merge :: [a] -> [a] -> [a]
merge xs     []     = xs
merge []     ys     = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
43
andri

Je veux proposer une version plus paresseuse de la fusion:

merge [] ys = ys
merge (x:xs) ys = x:merge ys xs

Pour un exemple d'utilisation, vous pouvez vérifier une récente SO question sur génération paresseuse de combinaisons .
La version de la réponse acceptée est inutilement stricte dans le deuxième argument et c'est ce qui est amélioré ici.

57
Daniel Velkov

Alors pourquoi pensez-vous que simple (concat. Transposer) "n'est pas assez joli"? Je suppose que vous avez essayé quelque chose comme:

merge :: [[a]] -> [a]
merge = concat . transpose

merge2 :: [a] -> [a] -> [a]
merge2 l r = merge [l,r]

Ainsi, vous pouvez éviter la récursivité explicite (par rapport à la première réponse) et c'est toujours plus simple que la deuxième réponse. Quels sont donc les inconvénients?

23
Ed'ka

EDIT: Jetez un œil à la réponse et aux commentaires d'Ed'ka!

Une autre possibilité:

merge xs ys = concatMap (\(x,y) -> [x,y]) (Zip xs ys)

Ou, si vous aimez les applications:

merge xs ys = concat $ getZipList $ (\x y -> [x,y]) <$> ZipList xs <*> ZipList ys
6
danlei

Certainement un cas pour un déroulement:

interleave :: [a] -> [a] -> [a]
interleave = curry $ unfoldr g
  where
    g ([], [])   = Nothing
    g ([], (y:ys)) = Just (y, (ys, []))
    g (x:xs, ys) = Just (x, (ys, xs))
4
idontgetoutmuch