Haskell mapping function with predicate

I feel this should be fairly obvious or easy, but I just can't get it. What I want to do is apply the function to the list (using the map), but only if saved. Imagine that you wanted to separate only those numbers:

map (`div` 2) (even) [1,2,3,4] 

And this will give out [1,1,3,2], since only even numbers will have a function applicable to them. Obviously this will not work, but is there a way to do this work without having to write a separate function that you can give the map? The filter is almost there, except that I also want to save elements for which the condition is not fulfilled, and just do not apply a function to them.

thanks

+6
filter functional-programming haskell map
source share
6 answers

If you do not want to define a separate function, use lambda.

 map (\x -> if (even x) then (x `div` 2) else x) [1,2,3,4] 

Or instead of a map, a list comprehension is more readable, I think.

 [if (even x) then (x `div` 2) else x | x <- [1,2,3,4]] 
+9
source share
 mapIf pf = map (\x -> if px then fx else x) 
+6
source share

In addition to PiotrLegnica's answer: Often it is easier to read if you declare a helper function instead of using lambda. Consider this:

 map helper [1..4] where helper x | even x = x `div` 2 | otherwise = x 

( [1..4] - sugar for [1,2,3,4] )

If you want to remove all other elements, consider using filter . filter removes all elements that do not satisfy the predicate:

 filter even [1..4] -> [2,4] 

So, you can build a map pipe and filter, than instead, use the following instead:

 map (`div` 2) $ filter even [1..4] [x `div` 2 | x <- [1..4], even x] 

Choose what you like best.

+3
source share

Create your own helper function creator:

 ifP pred fx = if pred x then fx else x custom_f = ifP even f map custom_f [..] 

(caveat: I don’t have access to the compiler right now. I think it works fine ...)

+2
source share

I like other, more general solutions, but in your special case you can leave with

 map (\x -> x `div` (2 - x `mod` 2)) [1..4] 
+1
source share

In most cases, existing answers come off, but according to my biased definition of "readable" (I like guards more than ifs, and where more than let ):

 mapIf pf = map f' where f' x | px = fx | otherwise = x 

ghci says it probably works

 ghci> let mapIf pf = map f' where f' x | px = fx | otherwise = x ghci> mapIf even (+1) [1..10] [1,3,3,5,5,7,7,9,9,11] 
0
source share

All Articles