On Wed, Apr 1, 2009 at 9:50 PM, Zachary Turner <divisortheory@gmail.com> wrote:


On Wed, Apr 1, 2009 at 7:45 PM, Michael P Mossey <mpm@alumni.caltech.edu> wrote:
What if I have a list xs, and I want to remove one item and replace it with another? The item to remove can be detected by a predicate function. The order of the items doesn't matter. How about this:

replaceItem :: (a -> Bool) -> a -> [a] -> [a]
replaceItem p new xs = new : snd (partition p xs)

This will actually replace all items that match the predicate with one copy of 'new'. It will also prepend 'new' even if no items match the predicate.

For another challenge, can someone explain to me how to write this in point-free style?

I used an intermediate helper function, but the replaceItem function is point free

choose :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b
choose pred yes _ val | (pred val) = yes val
choose _ _ no val = no val


replaceItem :: (a -> Bool) -> a -> [a] -> [a]
replaceItem pred rep = map (choose pred id (const rep))

Ok I looked at the OP again and apparently I didn't understand the wording of the question :P  I just thought it said to replace each element in the list that matched the predicate with the new item.

How about this?

replaceItem :: [a] -> (a -> Bool) -> a -> [a]
let replaceItem xs pred = (: filter (not.pred) xs)

Note that I changed the order of the arguments, the value now comes last.  But I think this still should be ok?