Quelques fois, je me suis retrouvé à vouloir un zip code> dans Haskell qui ajoute du remplissage à la liste plus courte au lieu de tronquer le plus long. C'est assez facile pour écrire. ( Cette approche devient laide lorsque vous essayez de Définir à ce stade, j'ai triché et juste utilisé suis-je surpluée sur une façon plus élégante de faire cela, ou est quelque chose comme monoïde code> fonctionne ici ici, mais vous pourriez également simplement passer les éléments que vous souhaitez utiliser pour le rembourrage.) zippad3 code>. J'ai tapé ce qui suit puis réalisé que bien sûr, cela ne fonctionne pas: p> longueur code> pour choisir La liste la plus longue et les coussinets les autres. P> zippad3 code> déjà défini quelque part? p> p>
4 Réponses :
Que diriez-vous de la tête code> et de essai d'essai: p> sa sortie: p> de la queue code> de la queue code> (nommé suivant code> et repos code> dans mon exemple ci-dessous)? < Pré> xxx pré>
Ce modèle revient beaucoup. Une solution que j'ai apprise de Paul Chiusano est la suivante:
*Main> zipPad3 ["foo", "bar", "baz"] [2, 4, 6, 8] [True, False] "" 0 False
[("foo",2,True),("bar",4,False),("baz",6,False),("",8,False)]
Il y a des moments où vous voulez pouvoir appliquer une fonction différente à la queue plutôt que de simplement fournir i Utilisez l'ancien lorsque je fais quelque chose comme Cependant, si vous vouliez simplement faire une version plus succincte de ce que vous avez, vous pouvez probablement se tourner vers Mapaccuml, mais ce n'est pas plus clair. et le ++ peut être coûteux. P> mempty code> ou zéros manuels également: zipwithtail (+) code>
et le premier quand j'ai besoin de faire quelque chose comme zipwithtail (* b) (A *) (\ da dB -> a * db + b * da) code> puisque le premier peut être beaucoup plus efficace que l'alimentation une valeur par défaut dans une fonction, et celle-ci un peu donc. p> zipPad as bs = done $ mapAccumL go as bs
where go (a:as) b = (as,(a,b))
go [] b = ([],(mempty,b))
done (cs, both) = both ++ fmap (\x -> (x, mempty)) cs
Un moyen plus simple de le faire est avec peut-être code>. Je vais illustrer avec Edward's
Formulation plus générale: import Data.Maybe
import Control.Applicative
zipWithTails l r f as bs = catMaybes . takeWhile isJust $
zipWith fMaybe (extend as) (extend bs)
where
extend xs = map Just xs ++ repeat Nothing
fMaybe a b = liftA2 f a b <|> fmap l a <|> fmap r b