Dear haskellers,

Dne 06/19/2013 02:27 PM, Milan Straka napsal(a):

Hi all,

-----Original message-----
From: Nikita Volkov <nikita.y.volkov@gmail.com>
Sent: 19 Jun 2013, 13:47

Hello guys!

A deadline of a discusssion on this has been reached. To review the discussion you can visit the archives. Following is a summarization.

1. Following is an implementation proposed by Schachaf Ben-Kiki, which in a combination with an `INLINABLE` pragma produces very impressive results by making even the primitive operations reimplemented in terms of it perform better:

insert: ~ +5% increase using alterF
delete: ~ +10% increase using alterF
I probably did not make myself clear enough -- the insert reimplemented
with alterF runs 5% slower (the running time is increased by 5%) and
similarly for delete.

I was playing with alterF to implement

-- If an element equal to `x` is present, return it. If not, add `x` to the cache.
cacheLookup :: (Ord a) => a -> State (M.Map a a) a
cacheLookup x = state (alterF x f)
  where
    f (Just y) = (y, Just y)
    f Nothing   = (x,  Just x)

and I realized that in the first case alterF needlessly reinserts y into the map, which introduces unnecessary traversal. So my suggestion for discussion is to define alterF as

data Alter a = Keep | Remove | Replace a
  deriving (Read, Show, Eq, Ord)

alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Alter a)) -> (Map k a -> f (Map k a))
--                                                  ^^^^^

where Alter gives the action to be performed on the map. It's just as Maybe, but it adds Keep to keep the map intact, if one neither wants to replace an element nor to remove it. Another little benefit is that it's more descriptive and makes alterF slightly more accessible to users. Like in my case cacheLookup becomes more readable:

cacheLookup x = state (alterF x f)
  where
    f (Just x') = (x', Replace x')
    f Nothing   = (x,  Keep)

It probably won't affect performance for the standard functions defined using alterF, but in cases like this it could help.

Best regards,
Petr