[GHC] #665: re-work of insert API

GHC trac at galois.com
Mon Jan 30 05:41:43 EST 2006


#665: re-work of insert API
-----------------------------------+----------------------------------------
  Reporter:  jpbernardy            |          Owner:         
      Type:  feature request       |         Status:  new    
  Priority:  normal                |      Milestone:         
 Component:  libraries/base        |        Version:  6.4.1  
  Severity:  normal                |     Resolution:         
  Keywords:  Data Map collections  |             Os:  Unknown
Difficulty:  Unknown               |   Architecture:  Unknown
-----------------------------------+----------------------------------------
Old description:

> I have been using 'Data.Map' from the library distributed with GHC/Hugs,
> and I quite like it.  Often though, I find myself needing a function
> that behaves like this:
>
> > import Data.Map (Map); import qualified Data.Map as Map hiding (Map)
> >
> > insert1 :: Ord k => k -> (Maybe v -> v) -> Map k v -> (v, Map k v)
> > insert1 k f m   = let v = f (Map.lookup k m)
> >                   in (v, Map.insert k v m)
>
> In words, we use a function to determine what to place in the map,
> depending on what is already in the map.  In the result, we return
> the new map, and the value that was inserted in the map.  Here is an
> example of how we may use this function:
>
> > example m           = insert1 0 v m
> >   where v Nothing   = 0
> >         v (Just n)  = n + 1
>
> Clearly, I can implement this function myself as above.  However, I was
> wondering if I can achieve the same, without searching in the map twice.
> I came up with the following:
>
> > insert2 :: Ord k => k -> (Maybe v -> v) -> Map k v -> (v, Map k v)
> > insert2 k f m   = (v,m')
> >   where
> >   v             = f r
> >   (r, m')       = Map.insertLookupWithKey g k v m
> >   g _ x _       = x
>
> Is there a more direct way to implement this function?  The use of
> lazyness
> in this case seems like an overkill.  If not, I would like to suggest
> that we
> add it to the API.  Also, it seems that some of the functions in
> the library are quite easy to implement in terms of this function,
> so perhaps they don't need to be in the API?
>
> > insertWith' :: Ord k => (v -> v -> v) -> k -> v -> Map k v -> Map k v
> > insertWith' f k v m = snd (insert2 k (maybe v (f v)) m)
> >
> > insertWithKey' :: Ord k => (k -> v -> v -> v) -> k -> v -> Map k v ->
> Map k v
> > insertWithKey' f k v m = snd (insert2 k (maybe v (f k v)) m)

New description:

 I have been using 'Data.Map' from the library distributed with GHC/Hugs,
 and I quite like it.  Often though, I find myself needing a function
 that behaves like this:
 {{{
 > import Data.Map (Map); import qualified Data.Map as Map hiding (Map)
 >
 > insert1 :: Ord k => k -> (Maybe v -> v) -> Map k v -> (v, Map k v)
 > insert1 k f m   = let v = f (Map.lookup k m)
 >                   in (v, Map.insert k v m)
 }}}
 In words, we use a function to determine what to place in the map,
 depending on what is already in the map.  In the result, we return
 the new map, and the value that was inserted in the map.  Here is an
 example of how we may use this function:
 {{{
 > example m           = insert1 0 v m
 >   where v Nothing   = 0
 >         v (Just n)  = n + 1
 }}}
 Clearly, I can implement this function myself as above.  However, I was
 wondering if I can achieve the same, without searching in the map twice.
 I came up with the following:
 {{{
 > insert2 :: Ord k => k -> (Maybe v -> v) -> Map k v -> (v, Map k v)
 > insert2 k f m   = (v,m')
 >   where
 >   v             = f r
 >   (r, m')       = Map.insertLookupWithKey g k v m
 >   g _ x _       = x
 }}}
 Is there a more direct way to implement this function?  The use of
 lazyness
 in this case seems like an overkill.  If not, I would like to suggest that
 we
 add it to the API.  Also, it seems that some of the functions in
 the library are quite easy to implement in terms of this function,
 so perhaps they don't need to be in the API?
 {{{
 > insertWith' :: Ord k => (v -> v -> v) -> k -> v -> Map k v -> Map k v
 > insertWith' f k v m = snd (insert2 k (maybe v (f v)) m)
 >
 > insertWithKey' :: Ord k => (k -> v -> v -> v) -> k -> v -> Map k v ->
 Map k v
 > insertWithKey' f k v m = snd (insert2 k (maybe v (f k v)) m)
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/665>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the Glasgow-haskell-bugs mailing list