Je me sens comme ça devrait être assez évident, ou facile, mais je ne peux tout simplement pas l'obtenir. Ce que je veux faire, c'est appliquer une fonction à une liste (en utilisant la carte code>) mais uniquement si une condition est maintenue. Imaginez que vous ne vouliez que diviser les chiffres qui étaient même:
map (`div` 2) (even) [1,2,3,4]
6 Réponses :
Si vous ne voulez pas définir une fonction séparée, utilisez Lambda. ou au lieu d'une carte, la compréhension de la liste, un peu plus lisible, je pense. P> [if (even x) then (x `div` 2) else x | x <- [1,2,3,4]]
@PPioTrlegnica: Dans ce cas, la compréhension de la liste peut être mauvaise pour la performance, car elle se traduit par ConcatMap code> qui provoque la création d'une couche superflue de listes.
@Fuzxxl: Exécutez GHC -DDDOMP-SIMPLE code>, vous verrez qu'aucune liste intermédiaire n'est créée. La valeur par défaut Réécrire les règles et autres passes d'optimisation sont plus intelligents que cela.
Oui. J'ai oublié cela. GHC est damné intelligent, parfois même si intelligente de retirer les barrages routiers que je mets pour bloquer son optimisation ... :)
mapIf p f = map (\x -> if p x then f x else x)
Notez que cela peut être transformé en un utilitaire plus général pour Foncteur code> S, non seulement listes, si vous modifiez
mapper code> sur
fmap code> dans ce qui précède.
En plus de la réponse de PioTrlegnica: Souvent, il est plus facile de lire si vous déclarez une fonction d'assistance au lieu d'utiliser une Lambda. Considérons ceci: ( Si vous souhaitez supprimer tous les autres éléments, envisagez d'utiliser afin que vous puissiez créer un tuyau de [1..4] code> est le sucre pour
[1,2,3,4] code>) p>
Filtre code>.
filtre code> supprime tous les éléments qui ne satisfont pas le prédicat: p>
carte code> et Filtre que ou utilisez la compréhension de la liste à la place: P>
map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]
Créez votre propre fabricant de fonctions d'assistrage:
ifP pred f x = if pred x then f x else x custom_f = ifP even f map custom_f [..]
Personnellement, j'appellerais ce quand code>, puisque code> si code> me fait penser qu'il devrait y avoir un cas
el / code> aussi, mais j'aime cette solution.
Surtout une arnaque des réponses existantes, mais selon ma définition biaisée de "lisible" (j'aime les gardes plus que les ifs, et où code> plus que
laisse code>):
ghci> let mapIf p f = map f' where f' x | p x = f x | otherwise = x
ghci> mapIf even (+1) [1..10]
[1,3,3,5,5,7,7,9,9,11]
J'aime les autres solutions plus générales, mais dans votre cas très spécial, vous pouvez vous éloigner avec
map (\x -> x `div` (2 - x `mod` 2)) [1..4]