I was wondering why replace is not in base. I thought, it's because it must be easy to implement with standard combinators. Although I do not like prefix syntax of Applicative I wrote it this way:

replace a b = map (bool <$> id <*> (const b) <*> (== a))

And was slightly surprised after seeing replace in Data.List.Utils:

replace old new l = join new . split old $ l

Are there non-opinion based reasons to prefer one than the other in public projects?


Your code is not a replacement for replace (pun intended). Its type signature is wrong. Your code has type Eq b => b -> b -> [b] -> [b], but replace should have type Eq a => [a] -> [a] -> [a] -> [a].

<$> and <*> are infix, not prefix.

I'd prefer this to your implementation:

replace' :: Eq b => b -> b -> [b] -> [b]
replace' a b = map (\x -> if (a == x) then b else x)

It does the exact same thing in the exact same way, but is simpler and more readable (even a novice Haskell programmer who has never heard of bool or <$> or <*> can read it). Even more important: it has a type signature.

If you'd decided to cut-and-paste the type signature of the function you wanted to replicate before starting, you would have found out that your version doesn't work as a replacement at compile time -- and if you'd looked at and thought about the type signature, you probably would have wondered why the extra []s were there, and figured it out even earlier.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.