I want to write a function which takes a list of elements l, a list of indices i, and a list of replacement values v. The function will replace the values in l corresponding to the indices in i with the corresponding value in v.
Example:
If l = [1,2,3,4,5,6], i = [0,2], and v = [166,667], then
replaceValues l i v == [166,2,667,4,5,6]
My function:
--Replace the values in list l at indices in i with the
-- corresponding value in v
replaceValues :: [a] -> [Int] -> [a] -> [a]
replaceValues l [] [] = l
replaceValues l i v = x ++ [head v] ++ (replaceValues (tail y) shiftedIndices (tail v))
where
(x,y) = splitAt (head i) l
--The indices must be shifted because we are changing the list
shiftedIndices = map ((-)((head i) + 1)) (tail i)
This function manages to correctly replace the value at the first index in i, but it misplaces all of the following values. In the example above, it would give the output [166,667,3,4,5,6].
The problem with your implementation is that you aren’t keeping track of which index you’re currently at.
First of all, you’re better off considering using
[(Int,a)]rather than[Int]and[a]arguments separate to ensure that the “lists” are equal in length.An alternate implementation is as follows:
What’s happening here:
Tag each value with its index
See if there’s a replacement value for that index: if there is, use it; otherwise, use the original value.