Reputation: 1
I want to implement the map function for specific indices only, like this:
mapFor :: (a -> a) -> [Int] -> [a] -> [a]
An example would look like this.
mapFor (+10) [0,2] [1,2,3,4] == [11,2,13,4]
Upvotes: 0
Views: 209
Reputation: 1
Thanks to @cornuz I figured it out.
mapFor f is xs = [if (i `elem` is) then f v else v | (i,v) <- zip [0..] xs]
If you see any issues, please let me know so I can fix them.
Upvotes: 0
Reputation: 71075
Play with the data to find the pattern, to fulfill the given requirements:
mapFor (+1) [0,2] [100,200,300,400] == [101,200,301,400] ==
= { [ 100, 200, 300, 400 ] -- values
[ 0, 1, 2, 3 ] -- indices
[ 0, 2 ] } -- places
--------------------------------------
= (100+1) : { [200, 300, 400 ] -- values
[ 1, 2, 3 ] -- indices
[ 2 ] } -- places
--------------------------------------
= (100+1) : 200 : { [300, 400 ] -- values
[ 2, 3 ] -- indices
[ 2 ] } -- places
--------------------------------------
= (100+1) : 200 : (300+1) : { [400 ] -- values
[ 3 ] -- indices
[] } -- places
--------------------------------------
=
........
where { ... }
signifies our transformation.
Then, generalize! -- by replacing concrete data with symbolic variables, and you've got yourself a working -- recursive -- code.
mapFor op places values = g [0..] places values
where
g (i:is) (p:ps) (v:vs) -- most general case
| i == p = ....
| otherwise = ....
g _ [] _ = .... -- base case
...... -- more corner cases, if any
Make sure you exhaust all possibilities with your patterns.
Upvotes: 2