I recently added an alterF
function to Data.Map
, which is a flipped form of Control.Lens.At.at
.
alterF :: (Ord k, Functor f)
=> (Maybe a -> f (Maybe a))
-> k
-> Map k a
-> f (Map k a)
alterF
is designed to be able to offer reasonable performance even for very "heavy" functors like []
and even when the keys are fairly expensive to compare. Unfortunately, it's somewhat slower than one might wish in the more common case of a light-weight functor and cheap-to-compare keys.
To patch this up, I've added GHC rewrite rules for the Const b
and Identity
functors, rewriting them to simpler implementations that are usually faster. I'm about to add yet another one, for . I added one for (,) b
(,) b
and then removed it. See the update below.
However, I'm a bit annoyed by the fact that I need a specific rule for (,) b
, because there are many other functors that follow the same pattern. In particular, any time a functor is defined
data F b1 b2 ... a = F e1 ... a ... e_n
where none of the e_k
mention a
, I should be able to rewrite it the same way. Is there some way to do this with GHC RULES
? Or will I have to wait for some more general rewriting system?
Update
Sadly, I realized that my rewrite rule for pairs was invalid (it was too strict), and repairing that made it much less clearly beneficial. So I've scrapped that rule for now. I think the general question remains interesting, however.