I want to replace an element in a list with a new value only at first time occurrence.
I wrote the code below but using it, all the matched elements will change.
replaceX :: [Int] -> Int -> Int -> [Int]
replaceX items old new = map check items where
check item | item == old = new
| otherwise = item
How can I modify the code so that the changing only happen at first matched item?
Thanks for helping!
The point is that
mapandf(checkin your example) only communicate regarding how to transform individual elements. They don’t communicate about how far down the list to transform elements:mapalways carries on all the way to the end.Let’s write a new version of
map— I’ll call itmapOncebecause I can’t think of a better name.There are two things to note about this type signature:
Because we may stop applying
fpart-way down the list, the input list and the output list must have the same type. (Withmap, because the entire list will always be mapped, the type can change.)The type of
fhasn’t changed toa -> a, but toa -> Maybe a.Nothingwill mean “leave this element unchanged, continue down the list”Just ywill mean “change this element, and leave the remaining elements unaltered”So:
Your example is now: